Reflect Spring HATEOAS 1.0+ API changes in the reference docs.
* Response customization * JSON output customization Closes #1962
This commit is contained in:
committed by
Greg L. Turnquist
parent
9d77d0d814
commit
f615cc6e18
@@ -3,9 +3,9 @@
|
||||
|
||||
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 https://github.com/SpringSource/spring-hateoas[Spring HATEOAS] and provides an extension hook that lets you alter the representation of resources that go out to the client.
|
||||
|
||||
== The `ResourceProcessor` Interface
|
||||
== The `RepresentationModelProcessor` Interface
|
||||
|
||||
Spring HATEOAS defines a `ResourceProcessor<>` interface for processing entities. All beans of type `ResourceProcessor<Resource<T>>` are automatically picked up by the Spring Data REST exporter and triggered when serializing an entity of type `T`.
|
||||
Spring HATEOAS defines a `RepresentationModelProcessor<>` interface for processing entities. All beans of type `RepresentationModelProcessor<EntityModel<T>>` are 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` similar to the following (which is taken from the Spring Data REST tests) to your `ApplicationContext`:
|
||||
|
||||
@@ -13,15 +13,15 @@ For example, to define a processor for a `Person` entity, add a `@Bean` similar
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public ResourceProcessor<Resource<Person>> personProcessor() {
|
||||
public RepresentationModelProcessor<EntityModel<Person>> personProcessor() {
|
||||
|
||||
return new ResourceProcessor<Resource<Person>>() {
|
||||
return new RepresentationModelProcessor<EntityModel<Person>>() {
|
||||
|
||||
@Override
|
||||
public Resource<Person> process(Resource<Person> resource) {
|
||||
public EntityModel<Person> process(EntityModel<Person> model) {
|
||||
|
||||
resource.add(new Link("http://localhost:8080/people", "added-link"));
|
||||
return resource;
|
||||
model.add(new Link("http://localhost:8080/people", "added-link"));
|
||||
return model;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -32,10 +32,10 @@ IMPORTANT: The preceding example hard codes a link to `http://localhost:8080/peo
|
||||
|
||||
== Adding Links
|
||||
|
||||
You can add links to the default representation of an entity by calling `resource.add(Link)`, as the preceding example shows. Any links you add to the `Resource` are added to the final output.
|
||||
You can add links to the default representation of an entity by calling `model.add(Link)`, as the preceding example shows. Any links you add to the `EntityModel` are added to the final output.
|
||||
|
||||
== Customizing the Representation
|
||||
|
||||
The Spring Data REST exporter executes any discovered `ResourceProcessor` instances before it creates the output representation. It does so by registering a `Converter<Entity, Resource>` instance with an internal `ConversionService`. This is the component responsible for creating the links to referenced entities (such as 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.
|
||||
The Spring Data REST exporter executes any discovered `RepresentationModelProcessor` instances before it creates the output representation. It does so by registering a `Converter<Entity, EntityModel>` instance with an internal `ConversionService`. This is the component responsible for creating the links to referenced entities (such as 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, you can completely replace the default outgoing JSON representation with your own. If you register your own `ConversionService` in the `ApplicationContext` and register your own `Converter<Entity, Resource>`, you can return a `Resource` implementation of your choosing.
|
||||
If your project needs to have output in a different format, however, you can completely replace the default outgoing JSON representation with your own. If you register your own `ConversionService` in the `ApplicationContext` and register your own `Converter<Entity, EntityModel>`, you can return a `EntityModel` implementation of your choosing.
|
||||
|
||||
@@ -24,7 +24,7 @@ public class ScannerController {
|
||||
// do some intermediate processing, logging, etc. with the producers
|
||||
//
|
||||
|
||||
Resources<String> resources = new Resources<String>(producers); // <4>
|
||||
CollectionModel<String> resources = CollectionModel.of(producers); // <4>
|
||||
|
||||
resources.add(linkTo(methodOn(ScannerController.class).getProducers()).withSelfRel()); // <5>
|
||||
|
||||
@@ -39,12 +39,12 @@ public class ScannerController {
|
||||
<1> This example uses constructor injection.
|
||||
<2> This handler plugs in a custom handler for a Spring Data finder method.
|
||||
<3> This handler uses the underlying repository to fetch data, but then does some form of post processing before returning the final data set to the client.
|
||||
<4> The results need to be wrapped up in a Spring HATEOAS `Resources` object to return a collection but only a `Resource` for a single item.
|
||||
<4> The results of type T need to be wrapped up in a Spring HATEOAS `CollectionModel<T>` object to return a collection. `EntityModel<T>` or `RepresentationModel<T>` are suitable wrappers for a single item, respectively.
|
||||
<5> Add a link back to this exact method as a `self` link.
|
||||
<6> Returning the collection by using Spring MVC's `ResponseEntity` wrapper ensures that the collection is properly wrapped and rendered in the proper accept type.
|
||||
====
|
||||
|
||||
`Resources` is for a collection, while `Resource` is for a single item. These types can be combined. If you know the links for each item in a collection, use `Resources<Resource<String>>` (or whatever the core domain type is rather than `String`). Doing so lets you assemble links for each item as well as for the whole collection.
|
||||
`CollectionModel` is for a collection, while `EntityModel` -- or the more general class `RepresentationModel` -- is for a single item. These types can be combined. If you know the links for each item in a collection, use `CollectionModel<EntityModel<String>>` (or whatever the core domain type is rather than `String`). Doing so lets you assemble links for each item as well as for the whole collection.
|
||||
|
||||
IMPORTANT: In this example, the combined path is `RepositoryRestConfiguration.getBasePath()` + `/scanners/search/listProducers`.
|
||||
|
||||
@@ -52,7 +52,7 @@ IMPORTANT: In this example, the combined path is `RepositoryRestConfiguration.ge
|
||||
== @RepositoryRestResource VS. @BasePathAwareController
|
||||
|
||||
If you are not interested in entity-specific operations but still want to build custom operations underneath `basePath`, such as Spring MVC views, resources, and others, use `@BasePathAwareController`.
|
||||
If you're using `@RepositoryRestResource` on your custom controller, it will only handle the request if your request mappings blend into the URI space used by the repository.
|
||||
If you're using `@RepositoryRestController` on your custom controller, it will only handle the request if your request mappings blend into the URI space used by the repository.
|
||||
It will also apply the following extra functionality to the controller methods:
|
||||
|
||||
. CORS configuration according as defined for the repository mapped to the base path segment used in the request mapping of the handler method.
|
||||
|
||||
Reference in New Issue
Block a user