#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:
43
rest/headers/README.adoc
Normal file
43
rest/headers/README.adoc
Normal 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(…))`.
|
||||
@@ -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>
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
1
rest/headers/src/test/resources/documentation.properties
Normal file
1
rest/headers/src/test/resources/documentation.properties
Normal file
@@ -0,0 +1 @@
|
||||
org.springframework.restdocs.outputDir=target/generated-snippets
|
||||
Reference in New Issue
Block a user