Consistent anchor names for headings in documentation.

This commit is contained in:
Oliver Drotbohm
2021-07-15 16:29:08 +02:00
parent 4a5e61a2df
commit e7e57c2e6f
15 changed files with 64 additions and 24 deletions

View File

@@ -33,12 +33,14 @@ The following example shows the corresponding XML configuration:
When your ApplicationContext comes across this bean definition, it bootstraps the necessary Spring MVC resources to fully configure the controller for exporting the repositories it finds in that `ApplicationContext` and any parent contexts.
[[customizing-sdr.adding-sdr-to-spring-mvc-app.required-config]]
== More on Required Configuration
Spring Data REST depends on a couple Spring MVC resources that must be configured correctly for it to work inside an existing Spring MVC application. We tried to isolate those resources from whatever similar resources already exist within your application, but it may be that you want to customize some of the behavior of Spring Data REST by modifying these MVC components.
You should pay special attention to configuring `RepositoryRestHandlerMapping`, covered in the next section.
[[customizing-sdr.adding-sdr-to-spring-mvc-app.required-config.mapping]]
=== `RepositoryRestHandlerMapping`
We register a custom `HandlerMapping` instance that responds only to the `RepositoryRestController` and only if a path is meant to be handled by Spring Data REST. In order to keep paths that are meant to be handled by your application separate from those handled by Spring Data REST, this custom `HandlerMapping` class inspects the URL path and checks to see if a repository has been exported under that name. If it has, the custom `HandlerMapping` class lets the request be handled by Spring Data REST. If there is no Repository exported under that name, it returns `null`, which means "`let other `HandlerMapping` instances try to service this request`".

View File

@@ -5,7 +5,7 @@ For security reasons, browsers prohibit AJAX calls to resources residing outside
Spring Data REST, as of 2.6, supports https://en.wikipedia.org/wiki/Cross-origin_resource_sharing[Cross-Origin Resource Sharing] (CORS) through https://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/web.html#mvc-cors[Spring's CORS] support.
[[customizing-sdr.configuring-cors.config]]
== Repository Interface CORS Configuration
You can add a `@CrossOrigin` annotation to your repository interfaces to enable CORS for the whole repository. By default, `@CrossOrigin` allows all origins and HTTP methods. The following example shows a cross-origin repository interface definition:
@@ -32,6 +32,7 @@ interface PersonRepository extends CrudRepository<Person, Long> {}
The preceding example enables CORS support for the whole `PersonRepository` by providing one origin, restricted to the `GET`, `POST`, and `DELETE` methods and with a max age of 3600 seconds.
[[customizing-sdr.configuring-cors.controller-config]]
== Repository REST Controller Method CORS Configuration
Spring Data REST fully supports https://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/web.html#controller-method-cors-configuration[Spring Web MVC's controller method configuration] on custom REST controllers that share repository base paths, as the following example shows:
@@ -53,6 +54,7 @@ public class PersonController {
NOTE: Controllers annotated with `@RepositoryRestController` inherit `@CrossOrigin` configuration from their associated repositories.
[[customizing-sdr.configuring-cors.global-config]]
== Global CORS Configuration
In addition to fine-grained, annotation-based configuration, you probably want to define some global CORS configuration as well. This is similar to Spring Web MVC'S CORS configuration but can be declared within Spring Data REST and combined with fine-grained `@CrossOrigin` configuration. By default, all origins and `GET`, `HEAD`, and `POST` methods are allowed.

View File

@@ -58,6 +58,7 @@ interface PersonRepository extends CrudRepository<Person, Long> {
Now the query method in the preceding example is exposed at `http://localhost:8080/people/search/names`.
[[customizing-sdr.configuring-the-rest-url-path.rels]]
== Handling `rel` Attributes
Since these resources are all discoverable, you can also affect how the `rel` attribute is displayed in the links sent out by the exporter.

View File

@@ -5,6 +5,7 @@ Sometimes, the behavior of the Spring Data REST `ObjectMapper` (which has been s
To accommodate the largest percentage of the use cases, Spring Data REST tries to render your object graph correctly. It tries to serialize unmanaged beans as normal POJOs, and tries to create links to managed beans where necessary. However, if your domain model does not easily lend itself to reading or writing plain JSON, you may want to configure Jackson's `ObjectMapper` with your own custom type mappings and (de)serializers.
[[customizing-sdr.custom-jackson-deserialization.abstract-classes]]
== Abstract Class Registration
One key configuration point you might need to hook into is when you use an abstract class (or an interface) in your domain model. Jackson does not, by default, know what implementation to create for an interface. Consider the following example:
@@ -46,6 +47,7 @@ public class MyCustomModule extends SimpleModule {
Once you have access to the `SetupContext` object in your `Module`, you can do all sorts of cool things to configure Jackon's JSON mapping. You can read more about how https://wiki.fasterxml.com/JacksonFeatureModules[Modules work on Jackson's wiki].
[[customizing-sdr.custom-jackson-deserialization.custom-serializers]]
== Adding Custom Serializers for Domain Types
If you want to serialize or deserialize a domain type in a special way, you can register your own implementations with Jackson's `ObjectMapper`. Then the Spring Data REST exporter transparently handles those domain objects correctly.

View File

@@ -3,6 +3,7 @@
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.
[[customizing-sdr.customizing-json-output.representation-model-processor]]
== The `RepresentationModelProcessor` Interface
Spring HATEOAS defines a `RepresentationModelProcessor<>` interface for processing entities. All beans of type `RepresentationModelProcessor&lt;EntityModel&lt;T&gt;&gt;` are automatically picked up by the Spring Data REST exporter and triggered when serializing an entity of type `T`.
@@ -29,11 +30,12 @@ public RepresentationModelProcessor<EntityModel<Person>> personProcessor() {
====
IMPORTANT: The preceding example hard codes a link to `http://localhost:8080/people`. If you have a Spring MVC endpoint inside your app to which you wish to link, consider using Spring HATEOAS's https://github.com/spring-projects/spring-hateoas#building-links-pointing-to-methods[`linkTo(...)`] method to avoid managing the URL.
[[customizing-sdr.customizing-json-output.adding-links]]
== Adding Links
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-sdr.customizing-json-output.customizing-representation]]
== Customizing the Representation
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.

View File

@@ -3,6 +3,7 @@
There are many options to tailor Spring Data REST. These subsections show how.
[[customizing-sdr.item-resource-uris]]
== Customizing Item Resource URIs
By default, the URI for item resources are comprised of the path segment used for the collection resource with the database identifier appended.

View File

@@ -37,6 +37,7 @@ public class BeforeSaveEventListener extends AbstractRepositoryEventListener {
One thing to note with this approach, however, is that it makes no distinction based on the type of the entity. You have to inspect that yourself.
[[events.annotated-handler]]
== Writing an Annotated Handler
Another approach is to use an annotated handler, which filters events based on domain type.

View File

@@ -1,6 +1,6 @@
[[spring-data-rest-reference]]
= Spring Data REST Reference Guide
Jon Brisbin, Oliver Gierke, Greg Turnquist, Jay Bryant
Jon Brisbin, Oliver Drotbohm, Greg Turnquist, Jay Bryant
:revnumber: {version}
:revdate: {localdate}
ifdef::backend-epub3[:front-cover-image: image:epub-cover.png[Front Cover,1050,1600]]

View File

@@ -4,6 +4,7 @@
This section details various ways to integrate with Spring Data REST components, whether from a Spring application that is using Spring Data REST or from other means.
[[integration.programmatic-links]]
== Programmatic Links
Sometimes you need to add links to exported resources in your own custom-built Spring MVC controllers. There are three basic levels of linking available:

View File

@@ -118,7 +118,6 @@ If you navigate to `/profile/persons` and look at the profile data for a `Person
} ]
}
----
<1> A detailed listing of the attributes of a `Person` resource, identified as `#person-representation`, lists the names
of the attributes.
<2> The supported operations. This one indicates how to create a new `Person`.

View File

@@ -3,6 +3,7 @@
This section documents Spring Data REST's usage of the Spring Data Repository paging and sorting abstractions. To familiarize yourself with those features, see the Spring Data documentation for the repository implementation you use (such as Spring Data JPA).
[[paging-and-sorting.paging]]
== Paging
Rather than return everything from a large result set, Spring Data REST recognizes some URL parameters that influence the page size and the starting page number.
@@ -29,7 +30,7 @@ public Page findByNameStartsWith(@Param("name") String name, Pageable p);
The Spring Data REST exporter recognizes the returned `Page` and gives you the results in the body of the response, just as it would with a non-paged response, but additional links are added to the resource to represent the previous and next pages of data.
[[paging-and-sorting.prev-and-next-links]]
[[paging-and-sorting.paging.prev-and-next-links]]
=== Previous and Next Links
Each paged response returns links to the previous and next pages of results based on the current page by using the IANA-defined link relations https://www.w3.org/TR/html5/links.html#link-type-prev[`prev`] and https://www.w3.org/TR/html5/links.html#link-type-next[`next`]. If you are currently at the first page of results, however, no `prev` link is rendered. For the last page of results, no `next` link is rendered.
@@ -57,7 +58,7 @@ curl localhost:8080/people?size=5
}
},
"_embedded" : {
... data ...
data
},
"page" : { <3>
"size" : 5,

View File

@@ -77,10 +77,12 @@ NOTE: For more details about the `profile` link, see <<metadata.alps>>.
Spring Data REST exposes a collection resource named after the uncapitalized, pluralized version of the domain class the exported repository is handling. Both the name of the resource and the path can be customized by using `@RepositoryRestResource` on the repository interface.
[[repository-resources.collection-resource.supported-methods]]
=== Supported HTTP Methods
Collections resources support both `GET` and `POST`. All other HTTP methods cause a `405 Method Not Allowed`.
[[repository-resources.collection-resource.supported-methods.get]]
==== `GET`
Returns all entities the repository servers through its `findAll(…)` method.
@@ -123,6 +125,7 @@ The `GET` method supports a single link for discovering related resources:
* `search`: A <<repository-resources.search-resource,search resource>> is exposed if the backing repository exposes query methods.
[[repository-resources.collection-resource.supported-methods.head]]
==== `HEAD`
The `HEAD` method returns whether the collection resource is available. It has no status codes, media types, or related resources.
@@ -137,6 +140,7 @@ The following methods are used if present (decending order):
For more information on the default exposure of methods, see <<repository-resources.methods>>.
[[repository-resources.collection-resource.supported-methods.post]]
==== `POST`
The `POST` method creates a new entity from the given request body.
@@ -167,10 +171,12 @@ The `POST` method supports the following media types:
Spring Data REST exposes a resource for individual collection items as sub-resources of the collection resource.
[[repository-resources.item-resource.supported-methods]]
=== Supported HTTP Methods
Item resources generally support `GET`, `PUT`, `PATCH`, and `DELETE`, unless explicit configuration prevents that (see "`<<repository-resources.association-resource>>`" for details).
[[repository-resources.item-resource.supported-methods.get]]
==== GET
The `GET` method returns a single entity.
@@ -200,6 +206,7 @@ The `GET` method supports the following media types:
For every association of the domain type, we expose links named after the association property. You can customize this behavior by using `@RestResource` on the property. The related resources are of the <<repository-resources.association-resource,association resource>> type.
[[repository-resources.item-resource.supported-methods.head]]
==== `HEAD`
The `HEAD` method returns whether the item resource is available. It has no status codes, media types, or related resources.
@@ -212,6 +219,7 @@ The following methods are used if present (decending order):
For more information on the default exposure of methods, see <<repository-resources.methods>>.
[[repository-resources.item-resource.supported-methods.put]]
==== `PUT`
The `PUT` method replaces the state of the target resource with the supplied request body.
@@ -237,6 +245,7 @@ The `PUT` method supports the following media types:
* application/hal+json
* application/json
[[repository-resources.item-resource.supported-methods-patch]]
==== `PATCH`
The `PATCH` method is similar to the `PUT` method but partially updates the resources state.
@@ -264,13 +273,14 @@ The `PATCH` method supports the following media types:
* https://tools.ietf.org/html/rfc6902[application/patch+json]
* https://tools.ietf.org/html/rfc7386[application/merge-patch+json]
[[repository-resources.item-resource.supported-methods.delete]]
==== `DELETE`
The `DELETE` method deletes the resource exposed.
===== Methods used for invocation
The following methods are used if present (decending order):
The following methods are used if present (descending order):
- `delete(T)`
- `delete(ID)`
@@ -289,6 +299,7 @@ The `DELETE` method has only one custom status code:
Spring Data REST exposes sub-resources of every item resource for each of the associations the item resource has. The name and path of the resource defaults to the name of the association property and can be customized by using `@RestResource` on the association property.
[[repository-resources.association-resource.supported-methods]]
=== Supported HTTP Methods
The association resource supports the following media types:
@@ -298,6 +309,7 @@ The association resource supports the following media types:
* POST
* DELETE
[[repository-resources.association-resource.supported-methods.get]]
==== `GET`
The `GET` method returns the state of the association resource.
@@ -309,6 +321,7 @@ The `GET` method supports the following media types:
* application/hal+json
* application/json
[[repository-resources.association-resource.supported-methods.put]]
==== `PUT`
The `PUT` method binds the resource pointed to by the given URI(s) to the resource. This
@@ -325,6 +338,7 @@ The `PUT` method supports only one media type:
* text/uri-list: URIs pointing to the resource to bind to the association.
[[repository-resources.association-resource.supported-methods.post]]
==== `POST`
The `POST` method is supported only for collection associations. It adds a new element to the collection.
@@ -335,6 +349,7 @@ The `POST` method supports only one media type:
* text/uri-list: URIs pointing to the resource to add to the association.
[[repository-resources.association-resource.supported-methods.delete]]
==== `DELETE`
The `DELETE` method unbinds the association.
@@ -350,10 +365,12 @@ The `POST` method has only one custom status code:
The search resource returns links for all query methods exposed by a repository. The path and name of the query method resources can be modified using `@RestResource` on the method declaration.
[[repository-resources.search-resource.supported-methods]]
=== Supported HTTP Methods
As the search resource is a read-only resource, it supports only the `GET` method.
[[repository-resources.search-resource.supported-methods.get]]
==== `GET`
The `GET` method returns a list of links pointing to the individual query method resources.
@@ -369,6 +386,7 @@ The `GET` method supports the following media types:
For every query method declared in the repository, we expose a <<repository-resources.query-method-resource,query method resource>>. If the resource supports pagination, the URI pointing to it is a URI template containing the pagination parameters.
[[repository-resources.search-resource.supported-methods.head]]
==== `HEAD`
The `HEAD` method returns whether the search resource is available. A 404 return code indicates no query method resources are available.
@@ -378,10 +396,12 @@ The `HEAD` method returns whether the search resource is available. A 404 return
The query method resource runs the exposed query through an individual query method on the repository interface.
[[repository-resources.query-resource.supported-method]]
=== Supported HTTP Methods
As the search resource is a read-only resource, it supports `GET` only.
[[repository-resources.query-resource.supported-method.get]]
==== `GET`
The `GET` method returns the result of the query execution.
@@ -401,6 +421,7 @@ The `GET` method supports the following media types:
* `application/hal+json`
* `application/json`
[[repository-resources.query-resource.supported-method.head]]
==== `HEAD`
The `HEAD` method returns whether a query method resource is available.

View File

@@ -7,10 +7,12 @@ Currently, only JSON representations are supported. Other representation types c
Sometimes, the behavior of the Spring Data REST `ObjectMapper` (which has been specially configured to use intelligent serializers that can turn domain objects into links and back again) may not handle your domain model correctly. There are so many ways you can structure your data that you may find your own domain model is not translated to JSON correctly. It is also sometimes not practical in these cases to try and support a complex domain model in a generic way. Sometimes, depending on the complexity, it is not even possible to offer a generic solution.
[[representations.serializers-and-deserializers]]
== Adding Custom Serializers and Deserializers to Jackson's ObjectMapper
To accommodate the largest percentage of use cases, Spring Data REST tries very hard to render your object graph correctly. It tries to serialize unmanaged beans as normal POJOs, and it tries to create links to managed beans where necessary. However, if your domain model does not easily lend itself to reading or writing plain JSON, you may want to configure Jackson's ObjectMapper with your own custom mappings, serializers, and deserializers.
[[representations.serializers-and-deserializers.abstract-classes]]
=== Abstract Class Registration
One key configuration point you might need to hook into is when you use an abstract class (or an interface) in your domain model. By default, Jackson does not know what implementation to create for an interface. Consider the following example:
@@ -35,21 +37,23 @@ To add your own Jackson configuration to the `ObjectMapper` used by Spring Data
----
@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
objectMapper.registerModule(new SimpleModule("MyCustomModule") {
@Override
public void setupModule(SetupContext context) {
context.addAbstractTypeResolver(
new SimpleAbstractTypeResolver().addMapping(MyInterface.class,
MyInterfaceImpl.class)
);
}
});
objectMapper.registerModule(new SimpleModule("MyCustomModule") {
@Override
public void setupModule(SetupContext context) {
context.addAbstractTypeResolver(
new SimpleAbstractTypeResolver()
.addMapping(MyInterface.class, MyInterfaceImpl.class));
}
});
}
----
====
Once you have access to the `SetupContext` object in your `Module`, you can do all sorts of cool things to configure Jackson's JSON mapping. You can read more about how `Module` instances work on https://wiki.fasterxml.com/JacksonFeatureModules[Jackson's wiki].
[[representations.serializers-and-deserializers.serializers]]
=== Adding Custom Serializers for Domain Types
If you want to serialize or deserialize a domain type in a special way, you can register your own implementations with Jackson's `ObjectMapper`, and the Spring Data REST exporter transparently handles those domain objects correctly. To add serializers from your `setupModule` method implementation, you can do something like the following:
@@ -59,6 +63,7 @@ If you want to serialize or deserialize a domain type in a special way, you can
----
@Override
public void setupModule(SetupContext context) {
SimpleSerializers serializers = new SimpleSerializers();
SimpleDeserializers deserializers = new SimpleDeserializers();

View File

@@ -2,9 +2,10 @@
= Tools
:spring-data-rest-root: ../../../..
== The HAL Browser
[[tools.hal-explorer]]
== The HAL Explorer
The developer of the http://stateless.co/hal_specification.html[HAL specification] has a useful application: https://github.com/mikekelly/hal-browser[the HAL Browser]. It is a web application that stirs in a little HAL-powered JavaScript. You can point it at any Spring Data REST API and use it to navigate the app and create new resources.
There is a useful application to explore APIs using the http://stateless.co/hal_specification.html[HAL specification]: https://github.com/toedter/hal-explorer[the HAL Explorer]. It is a web application that stirs in a little HAL-powered JavaScript. You can point it at any HAL API and use it to navigate the app and create new resources.
Instead of pulling down the files, embedding them in your application, and crafting a Spring MVC controller to serve them up, all you need to do is add a single dependency.
@@ -14,10 +15,10 @@ The following listing shows how to add the dependency in Maven:
[source,xml]
----
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-explorer</artifactId>
</dependency>
</dependencies>
----
====
@@ -28,14 +29,14 @@ The following listing shows how to add the dependency in Gradle:
[source,groovy]
----
dependencies {
compile 'org.springframework.data:spring-data-rest-hal-browser'
compile 'org.springframework.data:spring-data-rest-hal-explorer'
}
----
====
NOTE: If you use Spring Boot or the Spring Data BOM (bill of materials), you do not need to specify the version.
This dependency auto-configures the HAL Browser to be served up when you visit your application's root URI in a browser. (NOTE: http://localhost:8080 was plugged into the browser, and it redirected to the URL shown in the following image.)
This dependency auto-configures the HAL Explorer to be served up when you visit your application's root URI in a browser. (NOTE: http://localhost:8080 was plugged into the browser, and it redirected to the URL shown in the following image.)
image::hal-browser-1.png[]

View File

@@ -5,6 +5,7 @@ There are two ways to register a `Validator` instance in Spring Data REST: wire
In order to tell Spring Data REST you want a particular `Validator` assigned to a particular event, prefix the bean name with the event in question. For example, to validate instances of the `Person` class before new ones are saved into the repository, you would declare an instance of a `Validator<Person>` in your `ApplicationContext` with a bean name of `beforeCreatePersonValidator`. Since the `beforeCreate` prefix matches a known Spring Data REST event, that validator is wired to the correct event.
[[validation.assigning-validators]]
== Assigning Validators Manually
If you would rather not use the bean name prefix approach, you need to register an instance of your validator with the bean whose job it is to invoke validators after the correct event. In your configuration that implements `RepositoryRestConfigurer` or subclasses Spring Data REST's `RepositoryRestConfigurerAdapter`, override the `configureValidatingRepositoryEventListener` method and call `addValidator` on the `ValidatingRepositoryEventListener`, passing the event on which you want this validator to be triggered and an instance of the validator. The following example shows how to do so: