How to document top-level array as response payload with Spring REST Docs
Asked Answered
E

2

15

I am using Spring REST Docs to document a REST API. I'm trying to document the following API operations:

GET /subsystems
GET /subsystems/some_name

For example, a call to GET /subsystems/samba returns the following JSON object:

{ 
  "id": "samba", 
  "description": "..." 
}

You could use the following snippet which uses Spring REST Docs to document this API operation:

this.mockMvc.perform(
    get("/subsystems/samba").accept(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk()).andDo(
        document("subsystem").withResponseFields(
            fieldWithPath("id").description("Subsystem name"),
            fieldWithPath("description").description("Subsystem description")));

My problem is with the first operation: the call to GET /subsystems returns a JSON array:

[ 
  { 
    "id" : "samba", 
    "description" : "..." 
  }, 
  { "id" : "ownCloud", 
    "description" : "..." 
  },
  { "id" : "ldap", 
    "description" : "..." 
  } 
]

I could not find any example showing how to document this kind of result in the Spring REST Docs documentation. How should I do it?

Elizabetelizabeth answered 1/7, 2015 at 13:3 Comment(4)
i have the same problem have you resolve?Congest
No, sorry. Finally I decided not to use Spring REST Docs. It does not fit my needs at the moment. I think Spring REST Docs assumes a highest maturity level in the REST API (martinfowler.com/articles/richardsonMaturityModel.html) that my API does not fulfill (these restrictions assume you always must return a JSON object, never an array as a top-level element). Perhaps future versions of Spring REST Docs will relax these constraints for projects with simpler needs?Elizabetelizabeth
Spring REST Docs doesn't make any assumptions about the maturity level of your REST API. It provides support for level 3 APIs (allowing you to document your API's links), but can be used to document less mature APIs. In fact, the only constraint in 1.0 is that your API can be tested with Spring MVC Test.Marcela
Thanks @AndyWilkinson! I'll give Spring REST Docs a second chance. :-)Elizabetelizabeth
P
25

this is totally possible with Spring Rest Doc 1.0

this.mockMvc.perform(
    get("/subsystems").accept(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk()).andDo(
        document("subsystem").withResponseFields(
            fieldWithPath("[].id").description("Subsystem name"),
            fieldWithPath("[].description").description("Subsystem description")));

To document the array itself, use

this.mockMvc.perform(
    get("/subsystems").accept(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk()).andDo(
        document("subsystem").withResponseFields(
            fieldWithPath("[]").description("An array of subsystems"),
            fieldWithPath("[].id").ignore(),
            fieldWithPath("[].description").ignore()));

I have ignored the other two fields if you just want to document the array itself. You can combine both solutions as well.

Enjoy.

Edit: I learned from Andy Wilkinson that if you document the top level array, all fields are marked as documented. So if you want to document just the array, you can safely skip the ignores.

Perfectionism answered 4/11, 2015 at 19:11 Comment(3)
I've opened an issue to improve the documentationMarcela
Thanks @AndyWilkinson! (the link to the issue is github.com/spring-projects/spring-restdocs/issues/163).Elizabetelizabeth
This worked great on 1.1.0, but stopped working on 1.1.1 and is still not working on 1.1.2Ibbie
D
2

subsectionWithPath method of PayloadDocumentation works with [] as well, without necessary to ignore the rest of fields:

result.andDo(docHandler.document(
    responseFields(subsectionWithPath("[]").description("A list of objects")
)));
Decentralize answered 15/7, 2018 at 20:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.