Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is an excerpt projection not applied automatically for a Spring Data REST item resource?

Tags:

I made a projection which should expose nested entities:

@Projection(name = "inlineBusiness", types = { UserModel.class }) public interface InlineBusinessUserModelProjection {      String getUsername();      String getFirstName();      String getLastName();      Date getBirthdate();      String getEmail();      BusinessModel getBusiness(); } 

And the service repository:

@RepositoryRestResource(collectionResourceRel = "users", path = "users",        excerptProjection = InlineBusinessUserModelProjection.class) public interface UserRepository extends BaseDAO<UserModel> {..} 

for /users it works fine, the business field is exposed with nested entity, but when I call /users/1- nothing, also all the custom methods.. Seems like projection isn't involved on any methods except of /users Any ideas?

like image 853
nKognito Avatar asked May 13 '15 16:05

nKognito


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 is Java projection?

Java Projections are pure Java classes that serve as proxies for Caché classes within a Java application. They provide the communication link between Java client objects and the Caché Objects on the Caché data server. Typically, a Java application contains a Java projection for each Caché class in the database.


2 Answers

That works as designed. An excerpt projection is used whenever an instance of the target type (UserModel in your case) is used within in an _embedded clause. Thus the excerpt is some kind of preview used everywhere the resource itself is not rendered but pointed to. This is usually the case from collection resources or for associations.

Using an excerpt projection by default on an item resource doesn't really make sense from another point of view: excerpt projections are a read-only view on some domain object. If you return that view for an item resource by default, how would a client know which data it had to send to update the resource. A JSON document created for an excerpt projection, can't be simply taken, modified and used to send a PUT request to update the resource – by definition.

If you want to apply a projection to the item resource, populate the projection URI template variable with the name of the projection.

EDIT: In case the projections don't get applied if you manually select them make sure InlineBusinessUserModelProjection is actually registered for general use. Be sure the type is located in the very same package or sub-package of UserModel. Alternatively manually register the projection via RepositoryRestConfiguration.projectionConfiguration().addProjection(…). Manual configuration makes the use of @Projection on the projection type obsolete.

Read more on this topic in the Spring Data REST reference documentation.

like image 190
Oliver Drotbohm Avatar answered Oct 19 '22 23:10

Oliver Drotbohm


I'm not going to argue with @Oliver Drotbohm, as this is indeed the correct answer, however, if you want a cheeky workaround, just define a getter for the entity field with a slightly different name (using the OP's example):

BusinessModel getBusinessInline() { return this.businessModel; } 

Will result in a JSON payload of:

{     .     .     "businessInline": {"name":"stuff etc"}     .     . } 

Presuming your consuming service will accept that, then its an option.

Not big or clever, but it works.

like image 29
Sparm Avatar answered Oct 19 '22 22:10

Sparm