Пару недель назад Пару месяцев назад я смотрел, как собираюсь разрабатывать новый REST API для проекта Oracle Cloud. Однажды я планировал использовать декларативную инъекцию ссылок, созданную в Jersey 1.x Марком Хэдли. К сожалению, это еще не было переадресовано, поэтому я побеседовал с руководителем проекта, и я взялся за небольшую работу среднего размера по обновлению кода.
Одна из вещей, которая изменилась в новой версии, заключается в том, что в JAX-RS 2.0 есть объект Link поэтому вместо возможности вставлять только String и URI вы также можете вводить правильные атрибуты rel. Это означает, что существующие аннотации, закодированные Marc, были объединены в простой набор аннотаций как для заголовков Link, так и для внедренных свойств.
Эта функциональность теперь доступна вместе с простым примером. Оригинальная версия функции, которую я передал, имеет некоторые серьезные ограничения, которые будут описаны ниже, вам понадобится версия Джерси после версии 2.8, или вы можете создать образ 2.9-SNAPSHOT, который содержит мои изменения в настоящее время для реализации примера в этом блоге.
В этом блоге рассматривается использование этого нового API, чтобы обеспечить простое внедрение для API коллекций. Одним из распространенных шаблонов в сервисах RESTful, в частности, основанных на JSON, является наличие массива структурных связей на верхнем уровне структуры. Для целей этого блога я собираюсь следовать форме гипермедиа типа Collection + JSON .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
{ "collection" : { "version" : "1.0", "links" : [ ], "items" : [ ... ] }} |
Так что я могу вставить ссылки в следующем виде, но для ясности здесь не хватает пучка котлов. Это не самый аккуратный код; но в более позднем цикле должно быть возможно просто их несколько. Проект в настоящее время использует EL для доступа к свойствам — это дает преимущество, позволяющее записывать значения, поскольку вы можете представлять свойства. Я могу понять, что это не нравится некоторым; но я не уверен, вижу ли я какой-либо смысл в переходе на JavaScript в данный момент. Также не стоит удивляться аннотациям @Xml, я использую MOXy для генерации JSON — это не только XML.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
{ @XmlTransient private int limit, offset; // Getters for these @XmlTransient private int modelLimit; // Getters for these @InjectLink( resource = ItemsResource.class, method = "query", style = Style.ABSOLUTE, bindings = {@Binding(name = "offset", value="${instance.offset}"), @Binding(name = "limit", value="${instance.limit}") }, rel = "self" ) @XmlElement(name="link") private String href; @InjectLinks({ @InjectLink( resource = ItemsResource.class, style = Style.ABSOLUTE, method = "query", condition = "${instance.offset + instance.limit < instance.modelLimit}", bindings = { @Binding(name = "offset", value = "${instance.offset + instance.limit}"), @Binding(name = "limit", value = "${instance.limit}") }, rel = "next" ), @InjectLink( resource = ItemsResource.class, style = Style.ABSOLUTE, method = "query", condition = "${instance.offset - instance.limit >= 0}", bindings = { @Binding(name = "offset", value = "${instance.offset - instance.limit}"), @Binding(name = "limit", value = "${instance.limit}") }, rel = "prev" )}) @XmlElement(name="link") @XmlElementWrapper(name = "links") @XmlJavaTypeAdapter(Link.JaxbAdapter.class) List<Link> links; ....} |
Исходное портирование декларативного кода связывания, существующее в версии Jersey до 2.8, имело очень наивный код в отношении определения того, каким должен быть URI для конкретного ресурса, оно не могло работать с любыми ресурсами, которые не были в корне приложения. и не справится с параметрами запроса, которые так важны при работе с коллекциями.
Теоретически может быть несколько URI для определенного класса ресурсов; но этот код должен предполагать отображение 1: 1, текущая реализация содержит простой алгоритм, который использует метамодель Джерси, чтобы попытаться разработать структуру, если это не сработает, вы можете просто предоставить другую реализацию ResourceMappingContext .
Некоторые могут спросить, почему я должен использовать эти уродливые аннотации, когда может быть проще просто ввести сам URI? Причина в том, чтобы предоставлять метаданные, которые могут использовать другие инструменты. Одна из моих следующих работ — расширить эту работу для создания расширений гипермедиа, и для этого мне нужны вышеуказанные метаданные. (Ожидание одобрения запроса на извлечение , прежде чем я действительно смогу в него попасть).
Наконец, стоит отметить, что у модели подкачки есть свои проблемы, которые становятся очевидными, если вы рассматриваете коллекцию REST как некий массив, который можно безопасно перелистывать. Одновременные обновления вместе с отсутствием состояния означают, что клиент никогда не может быть уверен, что у него есть полная модель, и он должен ожидать, что некоторые элементы будут видны несколько раз при обновлении модели. Вместо этого следует рассмотреть схемы на основе курсора или связывания, что является еще одним хорошим напоминанием о том, почему вы всегда должны рассматривать URI как непрозрачный — серверу может понадобиться изменить его структуру в будущем. Но это совсем другой блог для другого дня …
| Ссылка: | Декларативные ссылки в Джерси 2.9 и выше от нашего партнера JCG Джерарда Дэвисона в блоге Джерарда Дэвисона . |