有选择地扩展 Spring Data Rest 响应中的关联

我有一个标准的Spring数据JPA和Spring data Rest设置,正确地将关联作为指向正确资源的链接返回。

{
    "id": 1,
    "version": 2,
    "date": "2011-11-22",
    "description": "XPTO",
    "_links": {
        "self": {
            "href": "http://localhost:8000/api/domain/1"
        },
        "otherDomain": {
            "href": "http://localhost:8000/api/domain/1/otherDomain"
        }
    }
}   

但是,在某些请求中,我希望扩展与“otherDomain”的关联(因此客户端不必执行N + 1请求即可获取完整数据)。

是否可以配置Spring Data Rest以以这种方式处理响应?


答案 1

默认响应必须保持不变,以确保请求的有效负载与返回的请求对称。但是,Spring Data REST引入了一个名为投影的功能(有关详细信息,请参阅JIRA票证),其工作原理如下:PUTGET

创建专用接口并添加要包含在响应中的所有属性:

public interface MyProjection {

  String getMyProperty();

  MyRelatedObject getOtherDomain();
}

您可以

  • 使用对接口进行注释,并将其放置在与域类型或其子包完全相同的包中@Projection
  • 或者使用 和 手动调用 手动注册投影(通过扩展和覆盖 )。RepositoryRestConfigurationprojectionConfiguration().addProjection(…)RepositoryRestMvcConfigurationconfigureRepositoryRestConfiguration(…)

这将导致为域类型公开的资源接受具有投影名称的参数(名称也是可配置的)。如果给定,我们将跳过默认渲染(包括渲染指向相关实体的链接,而不是嵌入它们),并让 Jackson 渲染支持给定接口的代理。projectionProjectionConfiguration

这方面的一个例子也可以在Spring RESTBucks项目中找到。有关接口定义,请参阅订单投影


答案 2

我的解决方案适用于所有请求,但有些人可能会发现它相关。

我有一个类似的情况,其中我将userPersons关联嵌套在我的User json响应中,如下所示:

{
"_embedded":{
  "users":[
     {
        "userName":"Albert"
        "userPersons":[
           {
              "personId":2356,
              "activeBoolean":1
           },
           {
              "personId":123617783,
              "activeBoolean":1
           }
        ],
        "_links":{
           "self":{
              "href":"http://localhost:8080/api/users/1"
           }
        }
     }
  ]

} }

我的基本实体是这样的:

@Entity
public class User {


...

@Getter @Setter
private String userName;

@Getter @Setter
@OneToMany(mappedBy = "user")
private Set<Userperson> userPersons;

}

和单个存储库:

@RepositoryRestResource
public interface UserRepo extends JpaRepository<User, Integer> {
}

我的解决方案是这样的:

通过简单地公开Userperson@RepositoryRestResource,Spring Data Rest将嵌入您的关联。

如果为嵌套类型定义@RepositoryRestResource,则 Spring Data Rest 将呈现指向资源的链接,而不是嵌入它。

如果需要内部业务逻辑的嵌套类型存储库,请将其设置为 @RepositoryRestResource(export = false),以具有相同的行为。

为了避免1 + N问题,您可以配置预先加载的关联,也许可以使用像这个家伙这样的@EntityGraph - 尽管我还没有找到在Spring Data Rest中实现这一点的最佳方法。