Inspired by this question, I've implemented an enhancement which makes the original answer (see below) obsolete.
If you use 1.0.0.BUILD-SNAPSHOT (available from https://repo.spring.io/libs-snapshot), you can now mark a field as ignored. Ignored fields count has having been documented without actually appearing in the documentation.
Given that you want to separate the documentation, having two document calls makes sense. In the first you can document the company name and the array of employees. In the second you document the employees array and mark the company name as ignored.
Your test would look something like this:
mockMvc.perform(get("/company/5").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("company",
responseFields(
fieldWithPath("companyName").description(
"The name of the company"),
fieldWithPath("employee").description(
"An array of the company's employees"))))
.andDo(document("employee",
responseFields(
fieldWithPath("companyName").ignored(),
fieldWithPath("employee[].name").description(
"The name of the employee"),
fieldWithPath("employee[].age").description(
"The age of the employee"))));
You'll end up with two directories of snippets, one named company
and one named employee
. You can then use the response-fields.adoc
snippet from each.
Original answer
There's no explicit support for ignoring a field when you're documenting a request or a response, but I think you can probably achieve what you want by using a preprocessor to remove the fields that you don't want to document.
Given that you want to separate the documentation, having two document
calls makes sense. In the first you can document the company name and the array of employees. In the second you need to preprocess the request to remove the company and then document the employees array.
Your test would look something like this:
mockMvc.perform(get("/company/5").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("company",
responseFields(
fieldWithPath("companyName").description(
"The name of the company"),
fieldWithPath("employee").description(
"An array of the company's employees"))))
.andDo(document("employee",
preprocessResponse(removeCompany()),
responseFields(
fieldWithPath("employee[].name").description(
"The name of the employee"),
fieldWithPath("employee[].age").description(
"The age of the employee"))));
Note the use of preprocessResponse
in the second document
call. removeCompany
returns a preprocessor that uses a custom ContentModifier
to remove company name from the response:
private OperationPreprocessor removeCompany() {
return new ContentModifyingOperationPreprocessor(new ContentModifier() {
@Override
public byte[] modifyContent(byte[] originalContent, MediaType contentType) {
ObjectMapper objectMapper = new ObjectMapper();
try {
Map<?, ?> map = objectMapper.readValue(originalContent, Map.class);
map.remove("companyName");
return objectMapper.writeValueAsBytes(map);
}
catch (IOException ex) {
return originalContent;
}
}
});
}
You'll end up with two directories of snippets, one named company
and one named employee
. You can then use the response-fields.adoc
snippet from each.
While the above will work, it's harder than it needs to be. I've opened an issue so that the preprocessing to modify the response's content will no longer be necessary.