Это действительно REST API RPC? Рой Филдинг, кажется, так думает

99

Большая часть того, что я думал о REST, по-видимому, неверна - и я не один такой. У этого вопроса длинный вводный курс, но он кажется необходимым, поскольку информация немного разрознена. Собственно вопрос стоит в конце, если вы уже знакомы с этой темой.

Из первого абзаца REST API Роя Филдинга должно быть гипертекстовое управление , довольно ясно, что он считает, что его работа широко неверно интерпретируется:

Меня разочаровывает количество людей, называющих любой интерфейс на основе HTTP REST API. Сегодняшним примером является API REST SocialSite . Это RPC. Он кричит RPC. На дисплее так много сцепления, что ему следует дать оценку X.

Далее Филдинг перечисляет несколько атрибутов REST API. Некоторые из них, похоже, противоречат как обычной практике, так и общим советам на SO и других форумах. Например:

  • REST API следует вводить без каких-либо предварительных знаний, кроме исходного URI (закладки) и набора стандартизованных типов мультимедиа, которые подходят для предполагаемой аудитории (т. Е. Должны быть поняты любым клиентом, который может использовать API). ...

  • REST API не должен определять фиксированные имена ресурсов или иерархии (очевидная связь клиента и сервера). ...

  • REST API должен тратить почти все свои описательные усилия на определение типов мультимедиа, используемых для представления ресурсов и управления состоянием приложения, или на определение расширенных имен отношений и / или разметки с поддержкой гипертекста для существующих стандартных типов мультимедиа. ...

Идея «гипертекста» играет центральную роль - гораздо больше, чем структура URI или значения HTTP-глаголов. «Гипертекст» определяется в одном из комментариев:

Когда я [Филдинг] говорю «гипертекст», я имею в виду одновременное представление информации и элементов управления, так что информация становится аффордансом, посредством которого пользователь (или автомат) получает выбор и выбирает действия. Гипермедиа - это просто расширение того, что означает текст, для включения временных привязок в медиапоток; большинство исследователей отказались от этого различия.

Гипертекст не обязательно должен быть HTML в браузере. Машины могут переходить по ссылкам, когда они понимают формат данных и типы отношений.

Я предполагаю на данный момент, но первые два пункта выше, похоже, предполагают, что документация API для ресурса Foo, которая выглядит следующим образом, приводит к тесной связи между клиентом и сервером и не имеет места в системе RESTful.

GET   /foos/{id}  # read a Foo
POST  /foos/{id}  # create a Foo
PUT   /foos/{id}  # update a Foo

Вместо этого агент должен быть вынужден обнаруживать URI для всех Foos, например, отправив запрос GET для / foos. (Эти URI могут соответствовать приведенному выше шаблону, но это не относится к делу.) В ответе используется тип мультимедиа, способный передавать, как получить доступ к каждому элементу и что с ним можно сделать, что дает начало третьему пункту выше. . По этой причине документация по API должна быть сосредоточена на объяснении того, как интерпретировать гипертекст, содержащийся в ответе.

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

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

Но это только мое лучшее предположение в данный момент.

Филдинг опубликовал продолжение, в котором он ответил на критику, что его обсуждение было слишком абстрактным, лишенным примеров и богатым жаргоном:

Другие попытаются расшифровать то, что я написал, способами, более прямыми или применимыми к некоторым практическим интересам сегодняшнего дня. Я, вероятно, не буду, потому что я слишком занят следующей темой, подготовкой к конференции, написанием нового стандарта, поездкой в ​​какое-то отдаленное место или просто делом мелочей, которые позволяют мне почувствовать, что я заработал свою зарплату.

Итак, два простых вопроса для экспертов REST с практическим мышлением: как вы интерпретируете то, что говорит Филдинг, и как вы применяете это на практике при документировании / внедрении REST API?

Изменить: этот вопрос является примером того, как трудно что-то узнать, если у вас нет названия для того, о чем вы говорите. Имя в данном случае - «Гипермедиа как механизм состояния приложения» (HATEOAS).

Рич Аподака
источник
26
Джон, Рич просто объясняет, что у него изменилось мышление. Там ничего субъективно или аргументированный об этом. Голосуйте, чтобы оставаться открытым - это один из лучших вопросов с меткой «отдых», который я видел на SO.
Кейт Гоган,
4
Кейт, «объясняя изменение мышления» - это то, что он должен делать в своем блоге, а не на SO.
Джон Сондерс
13
Он не объясняет своего изменения в мышлении, он спрашивает, верно ли его понимание.
aehlke
4
Отличное резюме. Я узнал больше из этого вопроса, чем из большинства ответов.
Мартин Конечны

Ответы:

21

Я думаю, что ваше объяснение в основном касается этого. URI - это непрозрачные идентификаторы, которые, по большей части, не должны передаваться за пределы URI закладки, который используется пользовательским агентом для доступа к приложению.

Что касается документирования, то этот вопрос задавался довольно много раз. Вы документируете свой тип мультимедиа вместе с элементами управления гиперссылками, которые он содержит (ссылки и формы), и модель взаимодействия, если хотите (см. AtomPub).

Если вы документируете URI или как их создавать, вы делаете это неправильно.

SerialSeb
источник
Это все еще правда? Существуют спецификации ответа API, такие как Ionspec, которые намеренно сделали эти URI частью ответа.
Шон Пьянка
Да у них есть. На этом этапе вопрос заключается в том, чтобы выяснить, являются ли эти задокументированные URI просто точками входа в приложение, которые гарантированно останутся (некоторые из них не редкость и довольно полезны), или, поскольку люди хотят генерации кода, они встроены из спецификацию прямо в код, не позволяя серверу сообщать клиенту, как он может что-то делать. Если клиент думает, что он знает из-за этого контракта, вы не в гипермедиа, вы используете современную модель мыла openapi с теми же проблемами, с которыми вы столкнулись 18 лет назад.
SerialSeb,
Верно то, что за последние 11 лет появилось много языков документации API, но основы не изменились. Я считаю, что ценность обнаружения этих ссылок или, по крайней мере, обнаружения шаблонов URI заключается в создании универсального клиентского кода многократного использования, который может их динамически использовать, что позволяет многим реализациям на стороне сервера повторно использовать один и тот же клиентский код. Встраивание URI продолжает усложнять такие сценарии, но если вы используете эти форматы, вы, как правило, тесно связываете сгенерированный клиент из этих спецификаций, поэтому вы уже потеряли эту функцию.
SerialSeb
8

Ваша интерпретация мне кажется правильной. Я верю, что ограничения Филдинга можно применить на практике.

Я действительно хотел бы, чтобы кто-нибудь опубликовал несколько хороших примеров того, как документировать интерфейс REST. Существует так много плохих примеров, поэтому иметь несколько реальных, на которые можно указать пользователям, было бы очень ценно.

Даррел Миллер
источник
2
Вот это да. Эта страница с моделью ресурсов вызвала у меня слезы. Будем надеяться, что это положит начало тенденции.
Darrel Miller
Жаль, что это, по сути, единственный пример такого API в сети! Что еще хуже, нет никаких хороших примеров клиентского кода, который вообще следует этому принципу (который я нашел).
jkp
1
@DarrelMiller Но разве эти типы носителей не слишком "специфичны"? Мне кажется, что их API действительно использует только один MIME : application/json, и что модель ресурсов - это действительно отношения. Я неправильно понял этот аспект REST? Я также прочитал один из ваших ответов SO, который, кажется, указывает на то, что этих контрактов с «одним атрибутом» следует избегать ...
edsioufi
2
@RichApodaca Ваша ссылка умерла от дизентерии. web.archive.org/web/20170409132237/https://kenai.com/projects/…
forresthopkinsa
5

Я искал хороший пример API, написанного после HATEOAS, и у меня возникли проблемы с его поиском (я обнаружил, что и SunCloud API, и материал AtomPub трудно применить к «нормальной» ситуации с API). Поэтому я попытался сделать реалистичный пример в своем блоге, который последовал совету Роя Филдингса о том, что значит быть правильной реализацией REST. Мне было очень сложно придумать этот пример, несмотря на то, что он в принципе довольно прост (просто сбивает с толку при работе с API, а не с веб-страницей). Я понимаю, с чем Рой возражал, и согласен, это просто сдвиг в мышлении, который нужно правильно реализовать для API.

Взгляните: Пример API с использованием Rest

Джереми
источник
4

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

Несколько хороших обсуждений REST и связанных с ним HATEOAS:

Преимущества (также) использования HATEOAS в RESTFul API

Как получить чашку кофе

Aehlke
источник
4

Для интересующихся я нашел подробный пример HATEOAS на практике в Sun Cloud API .

Рич Аподака
источник
2
Ссылка мертва. Архив
wha7ever
4

Большинство людей ошибаются в том, что (по крайней мере, я думаю) в мире REST вы не документируете свой «интерфейс отдыха», то, что вы документируете, является типом носителя, независимо от вашего сервера или службы.

Redben
источник
2

Я думаю, что за те годы, что REST существует сейчас, технологи пришли к пониманию концепции ресурса и того, что на самом деле является RESTful, а что нет.

Согласно модели зрелости Ричардсона, существует 4 уровня (0–3), которые определяют, насколько RESTful ваш API, причем 3 означает действительно RESTful API, как и предполагал Рой Филдинг.

Уровень 0 - это когда у вас есть один URI точки входа - например, SOAP.

Уровень 1 означает, что API может различать разные ресурсы и имеет более одной точки входа - все еще пахнет SOAP.

Уровень 2 - это когда вы используете HTTP-глаголы - в первую очередь GET, POST, DELETE. Это тот уровень, на котором действительно появляется REST.

На уровне 3 вы начинаете использовать элементы управления гипермедиа, чтобы сделать ваш API по- настоящему RESTful.

Рекомендуемые ссылки для дальнейшего чтения:

Сампада
источник
1

Совершенно верно. Кроме того, я хотел бы отметить, что шаблоны URI отлично подходят для приложения RESTful, если они взяты из документов, полученных с сервера (OpenSearch является подходящим примером). Для шаблонов URI вы документируете, где они используются и каковы ожидаемые заполнители в шаблоне, но не сами шаблоны. Немного вопреки тому, что сказал Ванфриден, это не исключение.

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

По вашему вопросу: наша нормативная документация раскрывает ресурсы, влияние различных методов на эти ресурсы, а также используемые типы мультимедиа представления и их схемы, а также на какие ресурсы указывают URI в этих представлениях.

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

Кейт Гоган
источник
1
Допустимо предоставлять шаблоны URI как часть вашего API, вне канала. ПОЖАЛУЙСТА, НЕ называйте это ОТДЫХОМ, потому что это не так. Это огромное количество взаимосвязей, и именно для этого был создан REST. Но, как вы сказали, REST подходит не для всех приложений. Так что не делайте вид, что каждое приложение является REST.
aehlke
1
Собственно, согласен. Я считаю, что это то, что я сказал. Однако я действительно не вижу веских причин для внеполосного предоставления шаблонов URI.
Кейт Гоган,
0

Предположим, GET /foos/createFormвызывается для получения значений полей формы, которые должны быть предоставлены, когда мы переходим к созданию POST /foos. Теперь этот конкретный URL, то есть 1, используемый для создания foos, должен быть упомянут в ответе GET /foos/createFormкак ссылка на действие отправки в соответствии с предложением Филдинга, верно?
Тогда в чем преимущество сопоставления действий с хорошо известными Http-глаголами с действиями, «соглашение по коду / конфигурации» аннулируется.

Redzedi
источник