Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I apply a projection to a Spring Data REST query method resource?

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?

like image 388
bluish Avatar asked Feb 06 '15 09:02

bluish


People also ask

What do spring data rest projections do?

Spring data REST Projection supports projecting only a selected fields from an entity representation. To do that, we can define those specific fields into our @Projection interface. Let's create a custom view of our Student entity with first name and last name fields.

What is projection in REST API?

What Are Projections? It is a common practice to use Domain Transfer Objects in REST API design as a method of separating the API from its underlying model. This is particularly relevant to Spring Data JPA REST where you may want to restrict what is visible to clients.

What does the @RepositoryRestResource annotation do?

@RepositoryRestResource is used to set options on the public Repository interface - it will automatically create endpoints as appropriate based on the type of Repository that is being extended (i.e. CrudRepository/PagingAndSortingRepository/etc).


1 Answers

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.

like image 95
Oliver Drotbohm Avatar answered Oct 07 '22 00:10

Oliver Drotbohm