如何将投影应用于Spring Data REST查询方法资源?

9

我正在使用Spring Data REST 2.1.4.RELEASE。

我创建了:

  • 一个名为Booking的实体,
  • 其REST库(扩展CrudRepository)名为BookingRepository
  • 以及一个投影BookingDetails(注释为@Projection(name =“details”,types = Booking.class)),用于返回一些爆炸的链接实体,例如ResourceActivityApplicant等。

客户端可以通过.../rest/bookings获取所有预订,并且JSON响应包括链接到相关实体的链接。如果添加?projection=details,则链接的实体将被爆炸并返回。这很好。

现在我在存储库中添加了此自定义方法

List<Booking> findByApplicant(@Param("applicant") Person applicant);

当客户端使用.../rest/bookings/search/findByApplicant?applicant=5调用时,似乎没有办法请求details投影。以下尝试将被忽略:
  • adding &projection=details to the query string
  • making the method always return BookingDetails:

    List<BookingDetails> findByApplicant(@Param("applicant") Person applicant);
    
总结一下,自定义搜索方法(findBy*)永远不会返回投影。除非您使用@RepositoryRestResource(excerptProjection = BookingDetails.class)注释存储库,但这会导致一些问题,首先是客户端必须始终使用相同的投影。那么我们如何允许用户在使用findBy*方法时也可以使用投影呢?

1
.../rest/bookings/search/findByApplicant?applicant=5 这样的 URL 并不是很符合 RESTful 的规范。那么 .../rest/bookings?applicant=5 呢? - user1907906
3
虽然这与原帖问题毫无关联,但这个URI有何不安全之处?确切地说,你不能仅根据定义来判断URI的安全性,它完全取决于通过它公开的资源是否遵循HTTP语义。资源的ID是/foo还是/conquer/the/world都是完全无关紧要的。话虽如此,Spring Data REST利用超媒体让客户端导航到资源,因此资源ID的结构甚至变得不再重要了:)。 - Oliver Drotbohm
该 URL 看起来像 RPC。当然,超媒体是个好东西。 - user1907906
4
URI没有气味,它们是不透明的。重要的是资源以及它们的行为 :)。 - Oliver Drotbohm
1个回答

15

我已经验证了Spring Data REST 2.2.1能够正常工作,所以请更新它。确保你的客户端实际上按照你的意图发送请求参数。在调试过程中,我发现如果不显式引用URI,例如cURL将丢弃查询参数。因此,请这样写:

curl http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details

不会发送任何查询参数。一旦引用URI,它就会发送。

curl 'http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details'

越来越受欢迎的HTTPie也采用了类似的方式。使用它所需的语法为:

http :8080/orders/search/findByApplicant applicant==5 projection==details

如果你无法通过那种方式使其工作,获取一个运行示例项目以供参考也是不错的选择。


2
非常感谢!我感到很愚蠢:几天前我用Spring Data REST 2.1.4测试了一下,但没有成功;然后我更新到2.2.1,但没有测试(我只测试了新的“excerptProjection”)。现在我测试了一下...我发现它可以工作!!我没想到这个功能刚好在我需要它的时候被实现了:D 现在我更正我的问题。感谢您,对浪费时间表示抱歉! - bluish
1
别担心。我也感觉有点傻,因为使用普通的未加引号的 cURL 没有任何参数。此外,当其他人遇到相同问题时,这些问题仍然是一个标准参考,所以很好能得到这些问题的解答 :)。很高兴它对你有用! - Oliver Drotbohm
你好,我遇到了类似的情况。上面的解决方案适用于自定义查询方法。但是如何在内置方法中添加投影呢?例如,如果我有一个订单实体,/orders将给我所有应用投影的订单。但是当我使用self.href链接搜索单个订单时,例如/orders/58fa7da00498e41f81a9f806,该投影不会被应用。我该怎么做才能实现这一点呢? - pvpkiran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接