In Spring REST Docs, I can document fields of a JSON response. Additionally, I can specify the type where I can either pass a JsonFieldType
, e.g. JsonFieldType.STRIGN
. This will actually be validated, meaning the test will fail when e.g. a number is returned instead.
(...)
.andDo( document( "one-valid-connection",
pathParameters( parameterWithName( "ip" ).description( "The requested IPv4 address." ) ),
responseFields(
fieldWithPath( "username" ).type( JsonFieldType.STRING ).description( "The name of the user that initiated the connection." ),
fieldWithPath( "ipAddress" ).type( JsonFieldType.STRING ).description( "The IPv4 address of the user." ),
fieldWithPath( "startTime" ).type( JsonFieldType.STRING ).description( "The time (ISO 8601 format) when the connection has been initiated." ),
fieldWithPath( "stopTime" ).type( JsonFieldType.STRING ).description( "The time (ISO 8601 format) when the connection has been terminated or `null` if connection is still active." )
)
) );
My question is, is it possible to write custom types to support e.g. IP addresses, ISO timestamps, Enums and maybe even valid numeric ranges and to support custom validation (e.g. regex or more complex logic)?
As pseudo code, something like
responseFields(
fieldWithPath( "username" ).type( JsonFieldType.STRING )
fieldWithPath( "ipAddress" ).type( CustomTypes.IPV4_ADDRESS ),
fieldWithPath( "startTime" ).type( CustomTypes.ISO8601_TIMESTAMP ),
fieldWithPath( "stopTime" ).type( CustomTypes.ISO8601_TIMESTAMP ),
fieldWithPath( "type" ).type( CustomTypes.CONNECTION_ENUM ),
fieldWithPath( "duration" ).type( CustomTypes.createIntRange(0,999999) )
)
IMHO, there is not any sane, straightforward (i.e. utilizing only points where Spring is open for extension) solution.
The main purpose of Spring Restdocs is to document, not validate API. As I browsed sources, actual instance of payload is tested only against predefined types. Values are not further analyzed. Although you can put any Object
as field descriptor type, i.e. you are not restricted only to objects of JsonFieldType
class, the whole object is essentially only converted toString
to be written into some asciidoc document, that's all.
BTW I elaborated with idea of using Restdocs as structure validation tool too. For my case I eventually found acceptable solution. The Spring Restdocs source is pretty closed, so based on my experience with exploring internals, I recommend you not to try any hacky solution such as overriding org.springframework.restdocs.payload.JsonContentHandler#determineFieldType
or org.springframework.restdocs.payload.JsonFieldTypeResolver#resolveFieldType
methods (which would require to break visibility protection by class-instrumenting tools anyway).
Another idea could be to use bean validation annotations.