Можно ли использовать ОПЦИИ REST API только в качестве запроса HATEOAS? - PullRequest
2 голосов
/ 29 мая 2020

Как я понял, REST ДОЛЖЕН использовать ограничение HATEOAS для правильной реализации. Насколько я понимаю, HATEOAS состоит в том, что в основном каждый ресурс должен делиться информацией о том, какие варианты связи у него есть и как потребитель может использовать эти параметры для достижения своей конечной цели.

Мой вопрос: можно ли использовать метод HTTP OPTIONS в качестве способ навигации по REST API. В основном ответ на запрос OPTIONS будет включать возможные действия, которые необходимо предпринять над ресурсом, которые позволят использовать API без знания конечных точек.

например, начальный запрос к API

HTTP OPTIONS /api

Может вернуть все ресурсы, доступные для потребления, и их отношения. Как массивное дерево для использования API и всего, что он может предложить. Эта идея не пренебрегает реализацией HATEOAS и в других ответах, но запрос OPTIONS позволит осуществлять навигацию без возврата данных, которые потребитель на самом деле может не захотеть использовать.

Это действительно плохая идея? Или это что-то, что обычно реализуется. В настоящее время я пытаюсь реализовать REST API, но мне трудно понять преимущества HATEOAS, если нет возможности перемещаться по API без фактического запроса данных, которые могут не обязательно понадобиться при использовании определенных конечных точек. И я предполагаю, что HATEOAS стремится заставить клиентов потреблять ресурсы по их взаимосвязи, а не жестко кодировать конечную точку?

Буду признателен за некоторые мнения по этой идее.


TL; DR

Может ли запрос HTTP OPTIONS действовать как способ навигации по REST API, возвращая, какие параметры связи доступны для запрошенного ресурса, без фактического возврата ресурса?

Brgds

1 Ответ

2 голосов
/ 29 мая 2020

Согласно RF C 7231

Метод OPTIONS HTTP запрашивает информацию о вариантах связи, доступных для целевого ресурса, либо на исходном сервере, либо на промежуточном посреднике. . Этот метод позволяет клиенту определять параметры и / или требования, связанные с ресурсом, или возможности сервера, не подразумевая действия ресурса.

...

Сервер, генерирующий Успешный ответ на OPTIONS ДОЛЖЕН отправлять любые поля заголовка, которые могут указывать на дополнительные функции, реализованные сервером и применимые к целевому ресурсу (например, Allow), включая потенциальные расширения, не определенные в этой спецификации. Полезная нагрузка ответа, если таковая имеется, может также описывать варианты связи в машинном или удобочитаемом представлении. Стандартный формат для такого представления не определяется данной спецификацией, но может быть определен в будущих расширениях HTTP. Сервер ДОЛЖЕН сгенерировать поле Content-Length со значением «0», если в ответе не должно быть отправлено тело полезной нагрузки.

Итак, в основном ответ на запрос OPTIONS сообщит вашему клиенту какие HTTP-операции могут выполняться на определенном ресурсе. Кроме того, допустимо настроить таргетинг всего сервера на использование * вместо указанного c URI ресурса.

Ответ на запрос OPTIONS может выглядеть следующим образом:

HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Date: Thu, 13 Oct 2016 11:45:00 GMT
Expires: Thu, 20 Oct 2016 11:45:00 GMT
Server: EOS (lax004/2813)
x-ec-custom-error: 1

в котором говорится, что определенный ресурс поддерживает упомянутые операции в заголовке Allow резонанса. Через заголовок Cache-Control клиент знает, что по умолчанию он может кэшировать ответы на безопасные запросы (GET и HEAD) на срок до 7 дней (значение указывается в секундах). Заголовок x-ec-custom-error определяет нестандартный заголовок, который указывается c для определенного программного обеспечения, в данном конкретном случае для сервера ECS . Согласно этому Q&A значение не задокументировано публично, и поэтому c.

в приложении *. Что касается возврата дерева проходимых ресурсов из данного ресурса, операция OPTIONS была по запросу, технически это возможно, однако некоторые системы могут создавать почти бесконечный список URI. Поэтому такая конструкция сомнительна для более крупных систем.

Насколько я понимаю, HATEOAS состоит в том, что в основном каждый ресурс должен делиться информацией о том, какие варианты коммуникации у него есть и как потребитель может использовать эти варианты для достижения своей конечной цели. .

Гипертекст как движок состояния приложения (HATEOAS) - это, по сути, просто требование для достаточно успешного использования модели взаимодействия, используемой в Интернете в течение десятилетий, и обеспечения таких же функциональных возможностей приложениям. Это позволило приложениям просматривать Интернет, как это делаем мы люди.

Отлично, но как это работает?

В Интернете мы используем ссылки, а Интернет формирует все время. Через веб-форму сервер может научить клиента, в основном, какие свойства поддерживает или ожидает определенный ресурс. Но это не все! Та же форма также сообщает вашему клиенту, куда отправить запрос (целевой URI), какой HTTP-метод использовать и, как правило, неявно указывается тип носителя, к которому полезная нагрузка должна быть сериализована при отправке запроса на сервер. Это, по сути, делает ненужной внеполосную документацию API, поскольку вся информация, необходимая клиенту для выполнения действительного запроса, уже предоставляется сервером.

На типичном веб-сайте у вас может быть таблица Записи, предлагающие возможность добавлять новые записи, обновлять или удалять существующие. Обычно такие ссылки скрыты за причудливыми изображениями, например, мусорная корзина для удаления записи и карандаш для редактирования существующей записи и т.п., где изображение представляет собой аффорданс. аффорданс определенных элементов дает понять, что вы должны с ними делать или какова цель этого элемента. Кнопка на странице хочет быть нажата, в то время как виджет ползунка хочет быть изменен, пока текстовое поле ожидает ввода пользователя. Поскольку приложения не так сильно хотят работать с изображениями, вместо этого используется другая концепция. Имена связей как раз служат этой цели. Т.е. если у вас есть страничная коллекция, состоящая из нескольких страниц по 25 записей, то есть вы, возможно, знакомы с виджетом, содержащим стрелки для перелистывания этой коллекции. Ссылка здесь обычно должна быть аннотированной с такими именами отношений ссылок, как self, next, prev, first или last. Назначение таких ссылок вполне понятно, некоторые другие, например prefetch, указывают на то, что ресурс может быть загружен в фоновом режиме на ранней стадии, поскольку весьма вероятно, что следующее действие может запросить его, поначалу может быть менее интуитивно понятным. Такие имена отношений ссылок должны быть стандартизированы или, по крайней мере, соответствовать механизму расширения Web Linking .

С помощью имен связей ссылок клиент, который знает, что искать URI, помеченные next, то есть будут по-прежнему работать, если сервер решит изменить свою схему URI, поскольку он обрабатывает URI довольно непрозрачно.

Конечно, и клиент, и сервер должны поддерживать один и тот же тип носителя, который, кроме того, способны представить такие возможности. Обычный application/json не может предоставить такую ​​поддержку. HAL JSON или JSON Hyper-Schema по крайней мере добавить поддержку ссылок и имен связей ссылок в документы на основе JSON, а hal-формы, halo + json (halform) и ion могут использоваться, чтобы научить клиента, как должен быть создан запрос. Вопрос здесь не в том, какой тип мультимедиа поддерживать, а в том, сколько разных типов вы хотите поддерживать, поскольку чем больше типов мультимедиа может обрабатывать ваш API, тем более вероятно, что он будет взаимодействовать с произвольными клиентами, не находящимися под вашим контролем.

Эти концепции позволяют вам в основном использовать элементы управления, указанные в ответе сервера, для «продвижения вашего рабочего процесса». По сути, то, что вы, как разработчик API, должны сделать, - это разработать взаимодействие клиента с вашим API таким образом, чтобы оно следовало определенному, как назвал его Джим Уэббер, протокол приложения домена или состояние. machine , как выразился Асбьёрн Ульсберг, которая в основном направляет клиента через его задачу, то есть заказ через API вашего магазина.

Короче говоря, HATEOAS можно сравнить с веб-серфингом для приложений, используя именованные ссылки отношения и подобные формы представления типов мультимедиа, которые позволяют вам выполнять действия исключительно с ответом, полученным с сервера напрямую, вместо того, чтобы запекать внешние знания, происходящие из некоторой страницы справочной документации (Swagger, OpenAPI и т.п.), в ваше приложение.

Но как тогда HATEOAS приносит пользу потребителю на практике?

Во-первых, ему не нужно обращаться к какой-либо внешней документации, кроме текущей спецификации типа носителя, хотя обычно она поддерживает хорошо известные типы мультимедиа уже поддерживаются в популярных фреймворках или, по крайней мере, позволяют добавлять поддержку через плагины или дополнительные библиотеки. Как только тип мультимедиа понят и поддерживается, взаимодействие со всеми службами, которые также поддерживают один и тот же тип мультимедиа, становится возможным, независимо от их домена. Это позволяет повторно использовать одну и ту же реализацию клиента для взаимодействия с сервисом A и сервисом B из коробки. В системах, подобных RP C, вам нужно сначала интегрировать API службы A, а если вы хотите взаимодействовать со службой B, вам также необходимо интегрировать этот API отдельно. Скорее всего, эти API-интерфейсы несовместимы и, следовательно, не позволяют повторно использовать одни и те же классы.

Не зная URL-адреса ресурса, потребитель может обнаружить его, просмотрев API, но они все равно будут жестко зависеть от фактического URL? Или цель HATEOAS - усилить действия на определенном ресурсе, т.е. потребитель знает конечную точку пользователя, но ему не нужно знать конечные точки для действий, которые нужно предпринять над ресурсом пользователя, потому что они предоставляются API?

Клиента обычно не волнует Что касается самого URI, он заботится о содержании, которое может предоставить URI. Сравните это с вашим типичным поведением в Интернете. Вы предпочитаете содержательный текст, который резюмирует, что связывает контент, чтобы вы могли решить, запрашивать ли этот ресурс, или вы предпочитаете синтаксический анализ и анализ URI, чтобы узнать, что он может делать? Однако в последнем случае минимизация или обфускация URI не принесет вам никакой пользы. Неуклюжий разработчик интерпретирует такие URI / ресурсы и реализует крошечный хак для взаимодействия с этой службой, предполагая, что URI / ресурс останется неизменным c. Т.е. вполне разумно рассмотреть URI /api/users/1 для возврата некоторых данных, связанных с пользователем, и на основе формата ответа написан крошечный класс Java, который ожидает получить поле для имени пользователя и поле для электронной почты, т.е. Если сервер теперь решает добавить дополнительные данные или переименовать свои поля, клиент внезапно не сможет дальше взаимодействовать с этой службой. И будьте уверены, что на практике, особенно в области EDI, вам придется взаимодействовать с клиентами, которые не предназначены для взаимодействия с Интернетом или где программисты реализовали свою собственную структуру JSON, которая не может взаимодействовать с изменением порядка элементов или не может обрабатывать дополнительные необязательные поля, хотя spe c содержит примечания по этим вопросам. Филдинг утверждал, что

REST API никогда не должен иметь «типизированных» ресурсов, значимых для клиента. Авторы спецификации могут использовать типы ресурсов для описания реализации сервера за интерфейсом, но эти типы должны быть неактуальными и невидимыми для клиента. Единственные типы, которые имеют значение для клиента, - это тип носителя текущего представления и стандартизированные имена отношений. [то же самое] ( Источник )

Вместо типизированных ресурсов следует использовать согласование типа содержимого для поддержки взаимодействия различных держателей стека в сети.

Таким образом, сам URI - это просто идентификатор ресурса, который в основном используется, чтобы узнать, куда отправить запрос. С помощью значимых имен связей ссылок клиент должен знать, что он заинтересован, например, http:/www.acme.com/rel/orders, если он хочет отправить заказ в службу, и просто ищет URI, который либо аннотирован этим именем реализации расширения Web Linking, либо тем, что к нему прикреплен URI. Является ли имя отношения ссылки просто аннотацией (т. Е. Дополнительным атрибутом в элементе URI) или URI, прикрепленным к имени отношения ссылки (т. Е. Как встроенный объект имени отношения ссылки), зависит от фактического типа носителя. Таким образом, если сервер когда-либо решит изменить свою схему URI или переместить ресурсы, по какой-либо причине, клиент все равно сможет найти URI таким образом, и ему будет наплевать на символы, присутствующие в URI, или нет. . Он просто рассматривает URI как непрозрачную вещь. Приятно то, что URI может быть аннотирован несколькими именами отношений ссылок одновременно, что позволяет серверу «предлагать» этот URI клиентам, которые поддерживают разные имена отношений ссылок. В случае форм URI для отправки запроса, вероятно, содержится в атрибуте action элемента формы или тому подобном.

Как вы, надеюсь, видите, с HATEOAS нет необходимость жесткой зависимости от URI, если так, то может быть зависимость от имени отношения ссылки. Он по-прежнему требует URI, чтобы узнать, куда отправить запрос, но, просматривая URI по сопутствующему имени отношения ссылки, вы делаете обработку URI намного более динамичной c, поскольку это позволяет серверу изменять URI в любое время, когда он хочет или должен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...