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

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

例:

如果一个资源用户具有属性角色(1-N关系)

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

如何通过javarest获得此function的最佳方法是什么?

@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(确实存在任何框架,或者它是手动的)

你的家伙怎么解决这个问题?

使用查询参数

您可以使用一个支持查询参数的方法来为您提供加载角色的可能性:

 @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 

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

 @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