Update field snippets to no longer document whole subsection by default

Previously, when a field was documented it would implicitly document
the whole subsection of the payload identified by that field. This
could lead to users inadvertently failing to document part of the
payload. Arguably, this was a bug as it violated REST Docs' principle
of producing accurate, detail documentation. However, fixing it
requires a breaking change as people may also be relying on this
behaviour. A balance needed to be struck so the fix is being made in
a minor release.

This commit introduces a new subsectionWithPath method which returns a
SubsectionDescriptor; a specialisation of FieldDescriptor. Users
that were intentionally relying on the old behaviour will have to
replace some usage of fieldWithPath with subsectionWithPath instead.
Users who were unintentionally relying on the old behaviour will have
to add some additional descriptors produced using fieldWithPath and
will receive more accurate documentation in return.

Closes gh-274
This commit is contained in:
Andy Wilkinson
2016-10-27 17:33:34 +01:00
parent 7bcfbd9e35
commit cbd96f301d
19 changed files with 830 additions and 252 deletions

View File

@@ -26,6 +26,7 @@ import static org.springframework.restdocs.operation.preprocess.Preprocessors.pr
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath
import static org.springframework.restdocs.restassured.operation.preprocess.RestAssuredPreprocessors.modifyUris
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration
@@ -75,8 +76,8 @@ class ApiDocumentationSpec extends Specification {
fieldWithPath('appprofile').description('the profile of grails used in this project'),
fieldWithPath('groovyversion').description('the version of groovy used in this project'),
fieldWithPath('jvmversion').description('the version of the jvm used in this project'),
fieldWithPath('controllers').type(JsonFieldType.ARRAY).description('the list of available controllers'),
fieldWithPath('plugins').type(JsonFieldType.ARRAY).description('the plugins active for this project'),
subsectionWithPath('controllers').type(JsonFieldType.ARRAY).description('the list of available controllers'),
subsectionWithPath('plugins').type(JsonFieldType.ARRAY).description('the plugins active for this project'),
)))
.when()
.port(this.serverPort)
@@ -123,14 +124,14 @@ class ApiDocumentationSpec extends Specification {
requestFields(
fieldWithPath('title').description('the title of the note'),
fieldWithPath('body').description('the body of the note'),
fieldWithPath('tags').type(JsonFieldType.ARRAY).description('a list of tags associated to the note')
subsectionWithPath('tags').type(JsonFieldType.ARRAY).description('a list of tags associated to the note')
),
responseFields(
fieldWithPath('class').description('the class of the resource'),
fieldWithPath('id').description('the id of the note'),
fieldWithPath('title').description('the title of the note'),
fieldWithPath('body').description('the body of the note'),
fieldWithPath('tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note'),
subsectionWithPath('tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note')
)))
.body('{ "body": "My test example", "title": "Eureka!", "tags": [{"name": "testing123"}] }')
.when()