9
votes

I'm using Spring Data REST 2.1.4.RELEASE.

I created

  • an entity Booking,
  • its REST repository (extending CrudRepository) named BookingRepository
  • and a projection BookingDetails (annotated with @Projection(name="details", types = Booking.class)) for returning some of its linked entities exploded, such as Resource, Activity, Applicant etc.

The client gets all bookings with .../rest/bookings and the JSON response includes links for the linked entities. If it adds ?projection=details then the linked entities are exploded and returned. And this is great.

Now I add this custom method to the repository:

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

When the client invokes it with .../rest/bookings/search/findByApplicant?applicant=5, there seem to be no way to request the details projection. Following attempts are ignored:

  • adding &projection=details to the query string
  • making the method always return BookingDetails:

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

Summarizing, custom search methods (findBy*) never return a projection. Unless you annotate the repository with @RepositoryRestResource(excerptProjection = BookingDetails.class), but this leads to some problems, first of all the client has to always use the same projection. How can we allow the user to use projections also with findBy* methods?

1
An URL like .../rest/bookings/search/findByApplicant?applicant=5 is not very RESTful. What about .../rest/bookings?applicant=5? - user1907906
While it's totally unrelated to the original posters question, what's unrestful about this URI? To be precise, you can't judge restfulness of a URI by definition as it solely depends on whether the resource exposed through it follows HTTP semantics. Whether the id of the resource is /foo or /conquer/the/world is completely irrelevant. That said, Spring Data REST leverages hypermedia to let clients navigate to the resources so the structure if the ids of the resources even becomes less that not relevant at all :). - Oliver Drotbohm
The URL smells like RPC. Of course hypermedia is a Good Thing. - user1907906
URIs don't smell, they're an opaque thing. It's the resources that matter and how they behave :). - Oliver Drotbohm

1 Answers

15
votes

I verfied this working with Spring Data REST 2.2.1, so please update it. Make sure your client actually sends the the requested parameters as you intend. While debugging, I found out that e.g. cURL drops query parameters if you do not explicitly quote the URI. So this:

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

will not send any of the query parameters. Once you quote the URI, it will.

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

Sort of the same is in place for the increasingly popular HTTPie. With it the required syntax is:

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

In case you can't get it to work that way, it would be cool to get a running example project to look at.