Search code examples
spring-restdocs

Spring RestDocs - document links in child documents?


How can I document links in child documents using Spring REST Docs?

Given the following JSON document:

{
  "links": {
    "alpha": "http://example.com/alpha",
    "beta": "http://example.com/beta"
  }
}

I can document the links by implementing a custom LinkExtractor as suggested in the reference docs (I have working implementation that is very similar to the HalLinkExtractor):

mockMvc.perform(get("/"))
    .andDo(document("root-resource",
        links(customLinkExtractor(),
            linkWithRel("alpha").description("Link to the Alpha resource"),
            linkWithRel("beta").description("Link to the Beta resource")
        )
    ));

However, my JSON document contains links sub-documents in other places, e.g.

{
    "links": {
        "alpha": "http://example.com/alpha",
        "beta": "http://example.com/beta",
    },
    "foo": {
        "links": {
            "gamma": "https://gamma.com/",
            "delta": "https://delta.com/"
        }
    }
}

How can I document the links document associated with the foo sub-document? Ideally, I would like to do something like:

mockMvc.perform(get("/"))
    .andDo(document("root-resource",
        links(customLinkExtractor(),
            linkWithRel("alpha").description("Link to the Alpha resource"),
            linkWithRel("beta").description("Link to the Beta resource")
        ),
        links(jsonPath("$.foo"), 
            customLinkExtractor(),
            linkWithRel("gamma").description("Link to the Gamma resource"),
            linkWithRel("delta").description("Link to the Delta resource")
        )
    ));

Naturally, this does not work since there is no jsonPath(..) method. What other options are available?

I guess that the same problem occurs if you are using the HalLinkExtractor and attempt to document links in the _embedded sub-document (see the example in the draft-kelly-json-hal).


Solution

  • I think you're on the right track with a custom link extractor. Rather than trying to use a separate jsonPath method, why not add that capability to the custom extractor? You could then tell it where to look for the links. For example:

    mockMvc.perform(get("/"))
        .andDo(document("root-resource",
            links(customLinkExtractor("$.links", "$.foo.links"),
                linkWithRel("alpha").description("Link to the Alpha resource"),
                linkWithRel("beta").description("Link to the Beta resource"),
                linkWithRel("gamma").description("Link to the Gamma resource"),
                linkWithRel("delta").description("Link to the Delta resource")
            )
        ));