DATAREST-449 - Polished up reference docs.
Original pull request: #170.
This commit is contained in:
committed by
Oliver Gierke
parent
707bac94c2
commit
462570fc24
@@ -1,6 +1,8 @@
|
||||
[[customizing-sdr.adding-sdr-to-spring-mvc-app]]
|
||||
= Adding Spring Data REST to an existing Spring MVC Application
|
||||
|
||||
NOTE: The following steps are unnecessary if you are using Spring Boot. Adding *spring-boot-starter-data-rest* will cause it to automatically to get added to your application.
|
||||
|
||||
If you have an existing Spring MVC application and you'd like to integrate Spring Data REST, it's actually very easy.
|
||||
|
||||
Somewhere in your Spring MVC configuration (most likely where you configure your MVC resources) add a bean reference to the JavaConfig class that is responsible for configuring the `RepositoryRestController`. The class name is `org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration`.
|
||||
|
||||
@@ -16,7 +16,7 @@ To change how the repository is exported, add a `@RestResource` annotation at th
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestResource(path = "people")
|
||||
@RepositoryRestResource(path = "people")
|
||||
interface PersonRepository extends CrudRepository<Person, Long> {}
|
||||
----
|
||||
|
||||
@@ -40,7 +40,7 @@ To change the segment of the URL under which this query method is exposed, use t
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestResource(path = "people")
|
||||
@RepositoryRestResource(path = "people")
|
||||
interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
@RestResource(path = "names")
|
||||
@@ -71,7 +71,7 @@ To change the rel value, use the `rel` property on the `@RestResource` annotatio
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestResource(path = "people")
|
||||
@RepositoryRestResource(path = "people")
|
||||
interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
@RestResource(path = "names", rel = "names")
|
||||
@@ -97,7 +97,7 @@ NOTE: These snippets of JSON assume you are using Spring Data REST's default for
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestResource(path = "people", rel = "people")
|
||||
@RepositoryRestResource(path = "people", rel = "people")
|
||||
interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
@RestResource(path = "names", rel = "names")
|
||||
@@ -153,7 +153,7 @@ For example, to skip exporting a Repository:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestResource(exported = false)
|
||||
@RepositoryRestResource(exported = false)
|
||||
interface PersonRepository extends CrudRepository<Person, Long> {}
|
||||
----
|
||||
|
||||
@@ -161,7 +161,7 @@ To skip exporting a query method:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestResource(path = "people", rel = "people")
|
||||
@RepositoryRestResource(path = "people", rel = "people")
|
||||
interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
@RestResource(exported = false)
|
||||
@@ -184,7 +184,7 @@ public class Person {
|
||||
}
|
||||
----
|
||||
|
||||
WARNING: Projections provide the means to change what is exported and effectively side step these settings. If you create any projections against the same domain object, it's your responsiblity to NOT export the fields.
|
||||
WARNING: Projections provide the means to change what is exported and effectively <<projections-excerpts.hidden-data,side step these settings>>. If you create any projections against the same domain object, it's your responsiblity to NOT export the fields. See
|
||||
|
||||
[[customizing-sdr.hiding-repository-crud-methods]]
|
||||
== Hiding repository CRUD methods
|
||||
@@ -193,7 +193,7 @@ If you don't want to expose a save or delete method on your `CrudRepository`, yo
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestResource(path = "people", rel = "people")
|
||||
@RepositoryRestResource(path = "people", rel = "people")
|
||||
interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,7 +45,7 @@ Once it finds a bean with this annotation, it iterates over the exposed methods
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RepositoryEventHandler
|
||||
@RepositoryEventHandler <1>
|
||||
public class PersonEventHandler {
|
||||
|
||||
@HandleBeforeSave
|
||||
@@ -60,9 +60,11 @@ public class PersonEventHandler {
|
||||
}
|
||||
----
|
||||
|
||||
<1> It's possible to narrow the types this handler applies against by using `@RepositoryEventHandler(Person.class)`.
|
||||
|
||||
The domain type whose events you're interested in is determined from the type of the first parameter of the annotated methods.
|
||||
|
||||
Just declare an instance of your annotated bean in your `ApplicationContext` and the `BeanPostProcessor` that is by default created in `RepositoryRestMvcConfiguration` will inspect the bean for handlers and wire them to the correct events.
|
||||
To register your event handler, either mark the class with one of Spring's `@Component` stereotypes so it can be picked up by `@SpringBootApplication` or `@ComponentScan`. Or declare an instance of your annotated bean in your `ApplicationContext`. Then the `BeanPostProcessor` that is created in `RepositoryRestMvcConfiguration` will inspect the bean for handlers and wire them to the correct events.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -75,3 +77,5 @@ public class RepositoryConfiguration {
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: Spring Data REST events are customized http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-functionality-events[Spring application events]. Spring events are synchronous by default, unless they get republished across a boundary (like issuing a WebSocket event or crossing into a thread).
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
Spring Data REST is itself a Spring MVC application and is designed in such a way that it should integrate with your existing Spring MVC applications with very little effort. An existing (or future) layer of services can run alongside Spring Data REST with only minor considerations.
|
||||
|
||||
To install Spring Data REST alongside your application, simply add the required dependencies, include the stock `@Configuration` class `RepositoryRestMvcConfiguration` (or subclass it and perform any required manual configuration), and map some URLs to be managed by Spring Data REST.
|
||||
|
||||
[[getting-started.boot]]
|
||||
== Adding Spring Data REST to a Spring Boot project
|
||||
|
||||
@@ -38,6 +36,8 @@ dependencies {
|
||||
|
||||
NOTE: You don't have to supply the version number if you are using the http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-gradle-plugin[Spring Boot Gradle plugin] or the http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-plugin[Spring Boot Maven plugin].
|
||||
|
||||
When using Spring Boot, Spring Data REST gets configured automatically.
|
||||
|
||||
[[getting-started.gradle]]
|
||||
== Adding Spring Data REST to a Gradle project
|
||||
|
||||
@@ -72,19 +72,61 @@ To install Spring Data REST alongside your existing Spring MVC application, you
|
||||
|
||||
IMPORTANT: This step is unnecessary if you are using Spring Boot's auto-configuration. Spring Boot will automatically enable Spring Data REST when you include *spring-boot-starter-data-rest* and either in your list of dependencies, and you your app is flagged with either `@SpringBootApplication` or `@EnableAutoConfiguration`.
|
||||
|
||||
In the following example, we'll subclass the standard `RepositoryRestMvcConfiguration` and add some `ResourceMapping` configurations for the `Person` domain object to alter how the JSON will look and how the links to related entities will be handled.
|
||||
Make sure you also configure Spring Data repositories for the store you use. For details on that, please consult the reference documentation for the http://projects.spring.io/spring-data/[corresponding Spring Data module].
|
||||
|
||||
[[getting-started.basic-settings]]
|
||||
== Basic settings for Spring Data REST
|
||||
|
||||
=== Changing the base URI
|
||||
|
||||
By default, Spring Data REST serves up REST resources at the root URI, "/". There are multiple ways to change the base path.
|
||||
|
||||
With Spring Boot 1.2+, all it takes is a single property in `application.properties`:
|
||||
|
||||
[source,properties]
|
||||
----
|
||||
spring.data.rest.basePath=/api
|
||||
----
|
||||
|
||||
With Spring Boot 1.1 or earlier, or if you are not using Spring Boot, simply do this:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Configuration
|
||||
@Import(RepositoryRestMvcConfiguration.class)
|
||||
public class MyWebConfiguration extends RepositoryRestMvcConfiguration {
|
||||
public class CustomizedRestMvcConfiguration extends RepositoryRestMvcConfiguration {
|
||||
|
||||
// … further configuration
|
||||
@Override
|
||||
public RepositoryRestConfiguration config() {
|
||||
RepositoryRestConfiguration config = super.config();
|
||||
config.setBasePath("/api");
|
||||
return config;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Make sure you also configure Spring Data repositories for the store you use. For details on that, please consult the reference documentation for the corresponding Spring Data module.
|
||||
In your Spring application configuration, introduce this with `@Import(CustomizedRestMvcConfiguration.class)`.
|
||||
|
||||
Both of these approaches will change the base path to `/api`.
|
||||
|
||||
=== Changing other Spring Data REST properties
|
||||
|
||||
There are many properties you can alter:
|
||||
|
||||
.Spring Boot configurable properties
|
||||
[cols="1,5". options="header"]
|
||||
|===
|
||||
| Name | Description
|
||||
|
||||
| basePath | root URI for Spring Data REST
|
||||
| defaultPageSize | change default number of items served in a single page
|
||||
| maxPageSize | change maximum number of items in a single page
|
||||
| pageParamName | change name of the query parameter for selecting pages
|
||||
| limitParamName | change name of the query parameter for number of items to show in a page
|
||||
| sortParamName | change name of the query parameter for sorting
|
||||
| defaultMediaType | change default media type to use when none is specified
|
||||
| returnBodyOnCreate | change if a body should be returned on creating a new entity
|
||||
| returnBodyOnupdate | change if a body should be returned on updating an entity
|
||||
|===
|
||||
|
||||
[[getting-started.bootstrap]]
|
||||
== Starting the application
|
||||
@@ -93,6 +135,14 @@ At this point, you must also configure your key data store.
|
||||
|
||||
Spring Data REST officially supports:
|
||||
|
||||
* http://projects.spring.io/spring-data-jpa/[Spring Data JPA]
|
||||
* http://projects.spring.io/spring-data-mongodb/[Spring Data MongoDB]
|
||||
* http://projects.spring.io/spring-data-neo4j/[Spring Data Neo4j]
|
||||
* http://projects.spring.io/spring-data-gemfire/[Spring Data GemFire]
|
||||
* http://projects.spring.io/spring-data-cassandra/[Spring Data Cassandra]
|
||||
|
||||
Here are some Getting Started guides to help you get up and running quickly:
|
||||
|
||||
* https://spring.io/guides/gs/accessing-data-rest/[Spring Data JPA]
|
||||
* https://spring.io/guides/gs/accessing-mongodb-data-rest/[Spring Data MongoDB]
|
||||
* https://spring.io/guides/gs/accessing-neo4j-data-rest/[Spring Data Neo4j]
|
||||
@@ -102,4 +152,6 @@ These linked guides introduce how to add dependencies for the related data store
|
||||
|
||||
You can run your application as either a Spring Boot app (with links showns above) or configure it as a classic Spring MVC app.
|
||||
|
||||
NOTE: In general Spring Data REST doesn't add functionality to a given data store. This means that by definition, it should work with any Spring Data project that supports the Repository programming model. The data stores listed above are simply the ones we have written integration tests to verify.
|
||||
|
||||
From this point, you can are free to <<customizing-sdr,customize Spring Data REST>> with various options.
|
||||
@@ -1,6 +1,6 @@
|
||||
[[intro-chapter]]
|
||||
= Introduction
|
||||
|
||||
REST web services have become the number one means for application integration on the web. In its core, REST defines that a system consists of resources that clients interact with. These resources are implemented in a hypermedia drive way. Spring MVC offers a solid foundation to build theses kinds of services but implementing very basic functionality of REST web service can be tedious and result in a lot of boilerplate code.
|
||||
REST web services have become the number one means for application integration on the web. In its core, REST defines that a system consists of resources that clients interact with. These resources are implemented in a hypermedia driven way. Spring MVC offers a solid foundation to build theses kinds of services. But implementing even the simplest tenet of REST web services for a multi-domain object system can be quite tedious and result in a lot of boilerplate code.
|
||||
|
||||
Spring Data REST builds on top of Spring Data repositories and automatically exports those as REST resources. It leverages hypermedia to allow clients to find functionality exposed by the repositories and allows to integrate the resources into related hypermedia based functionality as easy as possible.
|
||||
Spring Data REST builds on top of Spring Data repositories and automatically exports those as REST resources. It leverages hypermedia to allow clients to find functionality exposed by the repositories and integrates these resources into related hypermedia based functionality automatically.
|
||||
@@ -12,7 +12,7 @@ http://alps.io/[ALPS] is a data format for defining simple descriptions of appli
|
||||
Spring Data REST provides an ALPS document for every exported repository. It contains information about both the RESTful transitions
|
||||
as well as the attributes of each repository.
|
||||
|
||||
At the root of a Spring Data REST app is a *profile* link. Assuming you had an app with both *persons* and related *address*, the root
|
||||
At the root of a Spring Data REST app is a *profile* link. Assuming you had an app with both *persons* and related *addresses*, the root
|
||||
document would look like this:
|
||||
|
||||
[source,javascript]
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
Spring Data REST presents a default view of the domain model you are exporting. But sometimes, you may need to alter the view of that model for various reasons. In this section, you will learn how to define projections and excerpts to serve up simplified and reduced views of resources.
|
||||
|
||||
[[projections-excerpts.projections]]
|
||||
== Projections
|
||||
|
||||
Look at the following domain model:
|
||||
@@ -132,9 +133,10 @@ It's possible to have multiple projections.
|
||||
|
||||
NOTE: Visit <<spring-data-examples.projections>> to see an example project you can experiment with.
|
||||
|
||||
[[projections-excerpts.finding-projections]]
|
||||
=== Finding existing projections
|
||||
|
||||
Spring Data REST provides hypermedia metadata by exposing <<metadata.alps>> documents, a micro metadata format. To view the ALPS metadata, follow the `profile` link exposed by the root resource. If you navigate down to the ALPS document for `Person` resources (which would be `/alps/persons`), you can find many details about `Person` resources. Projections will be listed along with the details about the `GET` REST transitions, something like this:
|
||||
Spring Data REST exposes <<metadata.alps>> documents, a micro metadata format. To view the ALPS metadata, follow the `profile` link exposed by the root resource. If you navigate down to the ALPS document for `Person` resources (which would be `/alps/persons`), you can find many details about `Person` resources. Projections will be listed along with the details about the `GET` REST transition, something like this:
|
||||
|
||||
[source,javascript]
|
||||
----
|
||||
@@ -171,6 +173,7 @@ Spring Data REST provides hypermedia metadata by exposing <<metadata.alps>> docu
|
||||
<3> Further down you can see projection `noAddresses` listed.
|
||||
<4> The actual attributes served up by this projection include `firstName` and `lastName`.
|
||||
|
||||
[[projections-excerpts.hidden-data]]
|
||||
=== Bringing in hidden data
|
||||
|
||||
So far, you have seen how projections can be used to reduce the information that is presented to the user. Projections can also bring in normally unseen data. For example, Spring Data REST will ignore fields or getters that are marked up with `@JsonIgnore` annotations. Look at the following domain object:
|
||||
@@ -184,8 +187,8 @@ public class User {
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@JsonIgnore <1>
|
||||
private String password;
|
||||
@JsonIgnore private String password; <1>
|
||||
|
||||
private String[] roles;
|
||||
…
|
||||
----
|
||||
@@ -200,7 +203,7 @@ However, projections introduce the ability to still serve this field. It's possi
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Projection(name = "passwords", types = { User.class }) <2>
|
||||
@Projection(name = "passwords", types = { User.class })
|
||||
interface PasswordProjection {
|
||||
|
||||
String getPassword();
|
||||
@@ -211,9 +214,40 @@ If such a projection is created and used, it will side step the `@JsonIgnore` di
|
||||
|
||||
IMPORTANT: This example may seem a bit contrived, but it's possible with a richer domain model and many projections, to accidentally leak such details. Since Spring Data REST cannot discern the sensitivity of such data, it is up to the developers to avoid such situations.
|
||||
|
||||
Projections can also generate virtual data. Imagine you had the following entity definition:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
...
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
...
|
||||
}
|
||||
----
|
||||
|
||||
You can create a projection that combines these two data fields together like this:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Projection(name = "virtual", types = { Person.class })
|
||||
public interface VirtualProjection {
|
||||
|
||||
@Value("#{target.firstName} #{target.lastName}") <1>
|
||||
String getFullName();
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
<1> Spring's `@Value` annotation let's you plugin a SpEL expression that takes the target object, and splices together its `firstName` and `lastName` attributes to render a read-only `fullName`.
|
||||
|
||||
[[projections-excerpts.excerpts]]
|
||||
== Excerpts
|
||||
|
||||
An excerpt is a projection that is applied to a repository automatically. For an example, you can alter the `PersonRepository` as follows:
|
||||
An excerpt is a projection that is applied to a resource collection automatically. For an example, you can alter the `PersonRepository` as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -223,10 +257,11 @@ interface PersonRepository extends CrudRepository<Person, Long> {}
|
||||
|
||||
This directs Spring Data REST to use the `NoAddresses` projection when embedding `Person` resources into collections or related resources.
|
||||
|
||||
NOTE: Excerpt projections do NOT apply when rendering a single resource.
|
||||
NOTE: Excerpt projections to a single resource automatically. They have to be applied deliberately.
|
||||
|
||||
In addition to altering the default rendering, excerpts have additional rednering options as shown below.
|
||||
In addition to altering the default rendering, excerpts have additional rendering options as shown below.
|
||||
|
||||
[[projections-excerpts.excerpting-commonly-accessed-data]]
|
||||
== Excerpting commonly accessed data
|
||||
|
||||
A common situation with REST services arises when you compose domain objects. For example, a `Person` is stored in one table and their related `Address` is stored in another. By default, Spring Data REST will serve up the person's `address` as a URI the client must navigate. But if it's common for consumers to always fetch this extra piece of data, an excerpt projection can go ahead and inline this extra piece of data, saving you an extra `GET`. To do so, let's define another excerpt projection:
|
||||
|
||||
@@ -29,7 +29,7 @@ If the configuration values (`RepositoryRestConfiguration.returnBodyOnUpdate` an
|
||||
[[repository-resources.resource-discoverability]]
|
||||
=== Resource discoverability
|
||||
|
||||
A core principle of HATEOAS is that resources should be discoverable through the publication of links that point to the available resources. There are a few competing de-facto standards of how to represent links in JSON. By default, Spring Data REST uses http://tools.ietf.org/html/draft-kelly-json-hal[HAL] to render responses. HAL defines links to be contained in a property of the returned document.
|
||||
A core principle of https://spring.io/understanding/HATEOAS[HATEOAS] is that resources should be discoverable through the publication of links that point to the available resources. There are a few competing de-facto standards of how to represent links in JSON. By default, Spring Data REST uses http://tools.ietf.org/html/draft-kelly-json-hal[HAL] to render responses. HAL defines links to be contained in a property of the returned document.
|
||||
|
||||
Resource discovery starts at the top level of the application. By issuing a request to the root URL under which the Spring Data REST application is deployed, the client can extract a set of links from the returned JSON object that represent the next level of resources that are available to the client.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user