Spring RestDocs - ссылки на документы в дочерних документах?

Как я могу документировать ссылки в дочерних документах с помощью Spring REST Docs?

Учитывая следующий документ JSON:

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

Я могу задокументировать links, реализовав собственный LinkExtractor, как предлагается в reference docs (у меня есть рабочая реализация, которая очень похожа на 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")
        )
    ));

Однако мой документ JSON содержит links вложенных документов в других местах, например

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

Как я могу задокументировать links документ, связанный с foo суб-документом? В идеале хотелось бы сделать что-то вроде:

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")
        )
    ));

Естественно, это не работает, поскольку jsonPath(..) метода не существует. Какие еще варианты доступны?

Я предполагаю, что та же проблема возникает, если вы используете HalLinkExtractor и пытаетесь задокументировать ссылки в субдокументе _embedded (см. Пример в draft-kelly-json-hal).


person matsev    schedule 12.11.2015    source источник


Ответы (1)


Я думаю, что вы на правильном пути с экстрактором пользовательских ссылок. Вместо того, чтобы пытаться использовать отдельный jsonPath метод, почему бы не добавить эту возможность в настраиваемый экстрактор? Затем вы можете указать ему, где искать ссылки. Например:

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")
        )
    ));
person Andy Wilkinson    schedule 12.11.2015
comment
Я обновил свою реализацию, как вы предложили (с небольшим отклонением, что customLinkExtractor() всегда нужен полный путь jsonPath к документу links, например $.links). Однако теперь проблема в том, что я вижу только вывод ссылок gamma и delta в сгенерированном root-resource. В качестве альтернативы, если я удалю второй метод links() в приведенном выше фрагменте, я просто увижу ссылки alpha и beta, и тест пройдет успешно. - person matsev; 14.11.2015
comment
Извините, я упустил из виду тот факт, что второй вызов links перезапишет фрагмент, созданный первым. Я обновил свой ответ, применив подход, который позволит создать единый фрагмент со всеми ссылками. - person Andy Wilkinson; 14.11.2015
comment
Не беспокойтесь, теперь у меня это работает. Одним из недостатков этого подхода является то, что больше невозможно проверить, какие ссылки принадлежат $.links, а какие - $.foo.links. - person matsev; 14.11.2015
comment
Неплохо подмечено. Я открыл вопрос, чтобы изучить возможность некоторых улучшений в этой области. - person Andy Wilkinson; 14.11.2015