DATAREST-48 Fix a bug with compact content-type not displaying links properly when executing query methods.
This commit is contained in:
45
doc/changing_json.md
Normal file
45
doc/changing_json.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Customizing the JSON output
|
||||
|
||||
Sometimes in your application you need to provide links to other resources from a particular entity. For example, a
|
||||
`Customer` response might be enriched with links to a current shopping cart, or links to manage resources related to
|
||||
that entity. Spring Data REST provides integration with [Spring HATEOAS](https://github.com/SpringSource/spring-hateoas)
|
||||
and provides an extension hook for users to alter the representation of resources going out to the client.
|
||||
|
||||
### The ResourceProcessor interface
|
||||
|
||||
Spring HATEOAS defines a `ResourceProcessor<?>` interface for processing entities. All beans of type
|
||||
`ResourceProcessor<Resource<T>>` will be automatically picked up by the Spring Data REST exporter and triggered when
|
||||
serializing an entity of type `T`. For example, to define a processor for a `Person` entity, add a `@Bean` to your
|
||||
ApplicationContext like the following (which is taken from the Spring Data REST tests):
|
||||
|
||||
@Bean public ResourceProcessor<Resource<Person>> personProcessor() {
|
||||
return new ResourceProcessor<Resource<Person>>() {
|
||||
@Override public Resource<Person> process(Resource<Person> resource) {
|
||||
resource.add(new Link("http://localhost:8080/people", "added-link"));
|
||||
return resource;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
### Adding Links
|
||||
|
||||
It's possible to add links to the default representation of an entity by simply calling `resource.add(Link)` like the
|
||||
example above. Any links you add to the `Resource` will be added to the final output.
|
||||
|
||||
### Customizing the representation
|
||||
|
||||
The Spring Data REST exporter executes any discovered `ResourceProcessor`s before it creates the output representation.
|
||||
It does this by registering a `Converter<Entity, Resource>` instance with an internal `ConversionService`. This is the
|
||||
component responsible for creating the links to referenced entities (e.g. those objects under the "links" property in
|
||||
the object's JSON representation). It takes an `@Entity` and iterates over its properties, creating links for those
|
||||
properties that are managed by a `Repository` and copying across any embedded or simple properties.
|
||||
|
||||
If your project needs to have output in a different format, however, it's possible to completely replace the default
|
||||
outgoing JSON representation with your own. If you register your own `ConversionService` in the ApplicationContext and
|
||||
register your own `Converter<Person, Resource>`, then you can return a `Resource` implementation of your choosing.
|
||||
|
||||
For example, to rename the "links" property to "_links", create your own `Resource` subclass that renames the
|
||||
property using Jackson's `@JsonProperty` annotation:
|
||||
|
||||
public class MyResource extends Resource
|
||||
@@ -1,6 +1,6 @@
|
||||
# Handling ApplicationEvents in the REST Exporter
|
||||
|
||||
There are eight different events that the REST exporter emits throughout the process of working with an entity. Those are:
|
||||
There are six different events that the REST exporter emits throughout the process of working with an entity. Those are:
|
||||
|
||||
* BeforeSaveEvent
|
||||
* AfterSaveEvent
|
||||
@@ -8,8 +8,6 @@ There are eight different events that the REST exporter emits throughout the pro
|
||||
* AfterLinkSaveEvent
|
||||
* BeforeDeleteEvent
|
||||
* AfterDeleteEvent
|
||||
* BeforeRenderResourcesEvent
|
||||
* BeforeRenderResourceEvent
|
||||
|
||||
### ApplicationListener
|
||||
|
||||
@@ -110,28 +108,3 @@ You can pass the base package of the packages you want searched for handlers in
|
||||
<bean class="org.springframework.data.rest.repository.context.AnnotatedHandlerRepositoryEventListener">
|
||||
<property name="basePackage" value="com.mycompany.repository.handlers"/>
|
||||
</bean>
|
||||
|
||||
### Handling Render events
|
||||
|
||||
It's possible to alter the representation of the resource that gets sent back to the client. There are two possible reponses: a `org.springframework.data.rest.core.Resources` bean, which has a `content` and `links` property. The `content` property is a list of `org.springframework.data.rest.core.Resource` objects. In the case of JPA @Entities, these will actually be the `org.springframework.data.rest.core.MapResource` subclass of `Resource`. These helpers are what are run through the JSON mapper and used to produce the output sent to the client.
|
||||
|
||||
If, for example, you want to add links to the representation for a `Person`, you could define a POJO class and annotate it with `@RepositoryEventHandler(Person.class)` just like in the above example. Then you could define a couple of methods for altering the representations of the `Resources` and `Resource` objects that are sent to the client.
|
||||
|
||||
The `org.springframework.data.rest.core.Resources` bean is sent to the client whenever lists or results are required. If you call a query method or ask for a list of entities, then the `Resources` response is the one you'll get. If you ask for a specific entity's representation, however, you'll want to alter the plain `org.springframework.data.rest.core.Resource` bean.
|
||||
|
||||
An example handler class for these would look something like this:
|
||||
|
||||
@RepositoryEventHandler(Person.class)
|
||||
public class PersonRenderHandler {
|
||||
|
||||
@HandleBeforeRenderResources
|
||||
public void handleBeforeRenderResources(ServerHttpRequest request, RepositoryMetadata repoMeta, Resources resources) {
|
||||
resources.addLink(new SimpleLink("linkAddedByHandler", new URI("http://localhost:8080/linkAddedByHandler"));
|
||||
}
|
||||
|
||||
@HandleBeforeRenderResource
|
||||
public void handleBeforeRenderResource(ServerHttpRequest request, RepositoryMetadata repoMeta, Resource resource) {
|
||||
resource.addLink(new SimpleLink("linkAddedByHandler", new URI("http://localhost:8080/linkAddedByHandler"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ public class RepositoryRestController
|
||||
new Resources<String>(Collections.<String>emptyList()));
|
||||
}
|
||||
|
||||
Set<Link> links = new HashSet<Link>();
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
PagedResources.PageMetadata pageMetadata = null;
|
||||
|
||||
Iterator entities = Collections.emptyList().iterator();
|
||||
@@ -717,8 +717,8 @@ public class RepositoryRestController
|
||||
HttpStatus.OK,
|
||||
new HttpHeaders(),
|
||||
(null != pageMetadata
|
||||
? new PagedResources(results, pageMetadata)
|
||||
: new Resources(results)));
|
||||
? new PagedResources(results, pageMetadata, links)
|
||||
: new Resources(results, links)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user