Customizing requests and responses
There may be situations where you do not want to document a request exactly as it was sent or a response exactly as it was received. Spring REST Docs provides a number of preprocessors that can be used to modify a request or response before it is documented.
Preprocessing is configured by calling document
with an OperationRequestPreprocessor
or an OperationResponsePreprocessor
.
You can obtain instances by using the static preprocessRequest
and preprocessResponse
methods on Preprocessors
.
The following examples show how to do so:
this.mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andDo(document("index", preprocessRequest(modifyHeaders().remove("Foo")), (1)
preprocessResponse(prettyPrint()))); (2)
1 | Apply a request preprocessor that removes the header named Foo . |
2 | Apply a response preprocessor that pretty prints its content. |
this.webTestClient.get().uri("/").exchange().expectStatus().isOk().expectBody()
.consumeWith(document("index",
preprocessRequest(modifyHeaders().remove("Foo")), (1)
preprocessResponse(prettyPrint()))); (2)
1 | Apply a request preprocessor that removes the header named Foo . |
2 | Apply a response preprocessor that pretty prints its content. |
RestAssured.given(this.spec)
.filter(document("index", preprocessRequest(modifyHeaders().remove("Foo")), (1)
preprocessResponse(prettyPrint()))) (2)
.when()
.get("/")
.then()
.assertThat()
.statusCode(is(200));
1 | Apply a request preprocessor that removes the header named Foo . |
2 | Apply a response preprocessor that pretty prints its content. |
Alternatively, you may want to apply the same preprocessors to every test.
You can do so by using the RestDocumentationConfigurer
API in your @Before
method to configure the preprocessors.
For example, to remove the Foo
header from all requests and pretty print all responses, you could do one of the following (depending on your testing environment):
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).operationPreprocessors()
.withRequestDefaults(modifyHeaders().remove("Foo")) (1)
.withResponseDefaults(prettyPrint())) (2)
.build();
}
1 | Apply a request preprocessor that removes the header named Foo . |
2 | Apply a response preprocessor that pretty prints its content. |
private WebTestClient webTestClient;
@Before
public void setup() {
this.webTestClient = WebTestClient.bindToApplicationContext(this.context)
.configureClient()
.filter(documentationConfiguration(this.restDocumentation)
.operationPreprocessors()
.withRequestDefaults(modifyHeaders().remove("Foo")) (1)
.withResponseDefaults(prettyPrint())) (2)
.build();
}
1 | Apply a request preprocessor that removes the header named Foo . |
2 | Apply a response preprocessor that pretty prints its content. |
private RequestSpecification spec;
@Before
public void setup() {
this.spec = new RequestSpecBuilder()
.addFilter(documentationConfiguration(this.restDocumentation).operationPreprocessors()
.withRequestDefaults(modifyHeaders().remove("Foo")) (1)
.withResponseDefaults(prettyPrint())) (2)
.build();
}
1 | Apply a request preprocessor that removes the header named Foo . |
2 | Apply a response preprocessor that pretty prints its content. |
Then, in each test, you can perform any configuration specific to that test. The following examples show how to do so:
this.mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andDo(document("index", links(linkWithRel("self").description("Canonical self link"))));
this.webTestClient.get().uri("/").exchange().expectStatus().isOk()
.expectBody().consumeWith(document("index",
links(linkWithRel("self").description("Canonical self link"))));
RestAssured.given(this.spec)
.filter(document("index", links(linkWithRel("self").description("Canonical self link"))))
.when()
.get("/")
.then()
.assertThat()
.statusCode(is(200));
Various built-in preprocessors, including those illustrated above, are available through the static methods on Preprocessors
.
See below for further details.
Preprocessors
Pretty Printing
prettyPrint
on Preprocessors
formats the content of the request or response to make it easier to read.
Masking Links
If you are documenting a hypermedia-based API, you may want to encourage clients to navigate the API by using links rather than through the use of hard coded URIs.
One way to do so is to limit the use of URIs in the documentation.
maskLinks
on Preprocessors
replaces the href
of any links in the response with …
.
You can also specify a different replacement if you wish.
Modifying Headers
You can use modifyHeaders
on Preprocessors
to add, set, and remove request or response headers.
Replacing Patterns
replacePattern
on Preprocessors
provides a general purpose mechanism for replacing content in a request or response.
Any occurrences that match a regular expression are replaced.
Modifying URIs
If you use MockMvc or a WebTestClient that is not bound to a server, you should customize URIs by changing the configuration. |
You can use modifyUris
on Preprocessors
to modify any URIs in a request or a response.
When using REST Assured or WebTestClient bound to a server, this lets you customize the URIs that appear in the documentation while testing a local instance of the service.
Writing Your Own Preprocessor
If one of the built-in preprocessors does not meet your needs, you can write your own by implementing the OperationPreprocessor
interface.
You can then use your custom preprocessor in exactly the same way as any of the built-in preprocessors.
If you want to modify only the content (body) of a request or response, consider implementing the ContentModifier
interface and using it with the built-in ContentModifyingOperationPreprocessor
.