使用JPA Hibernate实体定义Rest API - LAZY和EAGER

时间:2017-02-09 21:06:36

标签: java rest cxf

如何为获取JPA实体的特定关系定义RESTFul Web服务API的最佳方法是什么?

示例:

如果a具有属性的用户具有属性角色(1-N关系)

我想有时候调用我的资源getUserByName(我不想因为性能而带来关系)和getUserByNameWithRoles(这里我想要关于evict双网络旅行)

使用java rest获得此功能的最佳方法是什么?

@Path("/user")
class UserResource{

  @GET
  @Path("/{name}")
  public Response getUserByName(@PathParam("name") String name){
    // hibernate query: select u from User u where u.name = :name
  }

  @GET
  // How I map this URL?
  @Path("/{name}") 
  public Response getUserByNameWithRoles(@PathParam("name") String name){
    // hibernate query: select u from User u inner join fetch u.roles where u.name = :name
  }

}

1)有2种方法吗?

2)使用一些“扩展”技巧,使用@QueryParam(确实存在任何框架,或者是手工制作)

你的家伙如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

使用查询参数

您可以使用一个支持查询参数的方法,以便您可以加载角色:

@GET
@Path("/{name}")
@Produces("application/json")
public Response getUserByName(@PathParam("name") String name,
                              @QueryParam("load-roles") boolean loadRoles) {
    ...
}

使用子资源

或者,您可以让端点仅返回用户的表示,而另一个端点仅返回用户角色的表示:

@GET
@Path("/{name}")
@Produces("application/json")
public Response getUserByName(@PathParam("name") String name) {
    ...
}

@GET
@Path("/{name}/roles")
@Produces("application/json")
public Response getRolesFromUserByName(@PathParam("name") String name) {
    ...
}

当需要角色时,只需向第二个端点执行请求即可返回角色。

使用自定义媒体类型

或者,您可以为资源的完整表示创建自定义媒体类型,并为部分表示设置自定义媒体类型。

使用这种方法,您将拥有以下方法:

@GET
@Path("/{name}")
@Produces({ "application/json", "application/vnd.company.partial+json" })
public Response getUserByName(@PathParam("name") String name) {
    ...
}

@GET
@Path("/{name}")
@Produces("application/vnd.company.full+json")
public Response getUserByNameWithRoles(@PathParam("name") String name) {
    ...
}

要请求部分代表您的资源,请求将如下:

GET /api/users/johndoe HTTP/1.1
Host: example.com
Accept: application/json
GET /api/users/johndoe HTTP/1.1
Host: example.com
Accept: application/vnd.company.partial+json

要请求资源的完整表示,请求将如下:

GET /api/users/johndoe HTTP/1.1
Host: example.com
Accept: application/vnd.company.full+json

答案 1 :(得分:0)

只需定义各种端点并调用服务或存储库类,即可在根实体上执行相应的查询,指定是否加载角色关系。

@Path("/{name}/withRoles")
public Response getUserByNameWithRoles(@PathParam("name") string name) {
  User user = userRepository.findByNameWithRoles( name );
  // translate your User to the response here.
}

@Path("/{name}")
public Response getUserByName(@PathParam("name") string name) {
  User user = userRepository.findByName( name );
  // translate your User to the response here.
}

在一天结束时,无论您使用框架X还是框架Y,概念和想法都保持相当直接和一致。

正如您所提到的,您可以使用@QueryParam传递一个标志,以指示是否使用或不使用角色填充User