Utilize Spring Restdocs DSL for validation

our REST API is documented by set of tests using Spring Restdocs in standard way (via mockMvc.perform(...)...andDo(document().fieldWithPath(...)) statement. Since fields have type and mandatory/optional flag, I play with idea to reuse this info for purpose of response body validation also in production code.

I moved Spring Restdocs to compile Maven scope and moved snippet creation to production code where it is visible for both the documenting test and response body interceptor in src/main code (the latter just calls ResponseFieldsSnippet.createModel method). Everything works fine except following pitfall: empty collection of objects looks like invalid since framework tries to match fieldWithPath rule of object field against nonexistent data.

For example, assuming JSON of cat is described as fieldWithPath("kittens[]"), fieldWithPath("kittens[].name"), the actual JSON {"kittens":[]} appears invalid since the latter descriptor is not satisfied. This doesn't happen for test samples where data is fabricated to maximize documentation benefit but it's issue for real cases.

Based on this observation, I tend to consider reusing Restdocs DSL for validation as a bad idea. Before switching to heavy-weight solution á la JSON schema, I would like to ask: does Restdocs offer some way to express field descriptors as tree rather than list of rules? For example above, something like fieldWithPath("kittens[]", subfieldWithPath("name")). (I think it could be useful regardless of how abusing is my case.)

I browsed and elaborated examples from documentation which seemed promising but AFAIK don't actually cover this case, namely: subsectionWithPath (which skips subtree), beneathPath (which focuses only to subtree) or ResponseFieldsSnippet.andWithPrefix (only shortcut for list creation but still list not tree).

Thanks for your opinion!

Upvotes: 1

Views: 328

Answers (1)

I finally found the problem is solved in newer library version, namely 1.2.5 and 2.0.2 (I had 1.2.2). The example above must be expressed as

fieldWithPath("kittens"),
fieldWithPath("kittens[]").optional(),
fieldWithPath("kittens[].name").type(STRING)

This setup says the kitten field itself is mandatory but the array is allowed to be empty and hence no field name is expected in such case (type of name must then be explicitly stated since library can't get clue from data).

More info: original issue, example above just as project test case, another examples can be found in commits linked from issue.

(Note: upgrading to 2.0.2 didn't work for me since it required also to upgrade Spring, which is not currently possible.)

The answer to original question is no, since Spring Restdocs still preserves the list format of field descriptors. However, after this fix it seems it doesn't bother me very much.

Upvotes: 1

Related Questions