#74 - More documentation within the REST headers example.

Added README to give more details on what the sample actually showcases. Added Spring RESTDocs to document HTTP interaction.
This commit is contained in:
Oliver Gierke
2015-04-08 19:33:04 +02:00
parent 8978423ade
commit 174710c5ba
4 changed files with 63 additions and 5 deletions

43
rest/headers/README.adoc Normal file
View File

@@ -0,0 +1,43 @@
= Spring Data REST - Headers example
This example shows how Spring Data REST auto-populates response headers for item resources and considers these values when conditional `GET` requests are used
== Auto-populated headers
If entities use optimistic locking (usually by demarcating a particular property as version property using a store-specific annotation), Spring Data REST will use the value stored in that property to populate the `ETag` header for `GET` and `HEAD` requests to the item resource.
If http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#auditing[Spring Data's auditing capabilities] are activated (using `@EnableJpaAuditing` in this case), the `Last-Modified` header is populated with the value of the last-modified property. See the `Customer` domain class for how to mark those.
== Conditional GET requests
The response headers can be used to issue conditional GET requests to save bandwidth in case the resource hasn't changed on the server:
.Conditional GET using If-Modified-Since
====
[source,bash]
----
$ curl http://localhost:8080/customers/1 -i -H "If-Modified-Since: Wed, 08 Apr 2015 17:24:20 GMT"
----
[source,http]
----
HTTP/1.1 304 Not Modified
----
====
.Conditional GET using If-None-Match
====
[source,bash]
----
$ curl http://localhost:8080/customers/1 -i -H "If-None-Match: 0"
----
[source,http]
----
HTTP/1.1 304 Not Modified
----
====
== Spring RESTDocs
The sample uses https://github.com/wilkinsona/spring-restdocs[Spring RESTDocs] to document the HTTP interaction implemented using the test cases. See `WebIntegrationTests.setUp()` for general setup and the individual test methods with their usage of `….andDo(document(…))`.

View File

@@ -11,7 +11,7 @@
<artifactId>spring-data-rest-examples</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</parent>
<properties>
<spring-data-releasetrain.version>Gosling-BUILD-SNAPSHOT</spring-data-releasetrain.version>
</properties>
@@ -22,7 +22,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
@@ -33,6 +33,13 @@
<artifactId>hsqldb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs</artifactId>
<version>0.1.0.BUILD-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -16,6 +16,7 @@
package example.orders;
import static org.springframework.http.HttpHeaders.*;
import static org.springframework.restdocs.RestDocumentation.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@@ -28,6 +29,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.restdocs.config.RestDocumentationConfigurer;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
@@ -51,7 +53,10 @@ public class WebIntegrationTests {
@Before
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(context).build();
this.mvc = MockMvcBuilders.webAppContextSetup(context).//
apply(new RestDocumentationConfigurer()).//
build();
}
@Test
@@ -67,11 +72,13 @@ public class WebIntegrationTests {
// ETag-based
mvc.perform(get(uri).header(IF_NONE_MATCH, response.getHeader(ETAG))).//
andExpect(status().isNotModified());
andExpect(status().isNotModified()).//
andDo(document("if-none-match"));
// Last-modified-based
mvc.perform(get(uri).header(IF_MODIFIED_SINCE, response.getHeader(LAST_MODIFIED))).//
andExpect(status().isNotModified());
andExpect(status().isNotModified()).//
andDo(document("if-modified-since"));
}
}

View File

@@ -0,0 +1 @@
org.springframework.restdocs.outputDir=target/generated-snippets