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

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

Из первого абзаца REST API Roy Fielding следует руководствоваться гипертекстом , довольно ясно, что он считает, что его работа широко неверно истолкована:

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

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

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

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

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

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

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

Hypertext не обязательно должен быть 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 с практическим мышлением: как вы интерпретируете то, что говорит Филдинг, и как вы применяете его на практике при документировании / внедрении API REST?

Редактировать: этот вопрос является примером того, как трудно научиться чему-то, если у вас нет имени того, о чем вы говорите. В этом случае именем называется «Hypermedia as Engine of Application State» (HATEOAS).

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

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

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

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

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

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

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

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

Некоторые хорошие дискуссии по REST и связанным с ними HATEOAS:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Что такое модель зрелости Ричардсона?
  • Блог Мартина Фаулера: Модель зрелости Ричардсона

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

Interesting Posts

Android M – проверить разрешение во время выполнения – как определить, проверен ли пользователь «Никогда не спрашивать снова»?

Как записи процесса Hadoop разбиваются по границам блоков?

Android: правильный способ использования onBackPressed () с помощью Toast

Как выбрать гиперссылку в виде текста в браузере?

Ошибка генерации клиента WebService с помощью JDK8

Поиск подстроки в имени файла со встроенным поиском окон

android: перемещение вида при перемещении касания (ACTION_MOVE)

Повреждение файлов после копирования файлов в Windows 7 64 бит с использованием двух методов

Java String не работает

Могу ли я запустить этот макрос быстрее?

Для чего нужны macros C?

Попытка запуска нескольких HTTP-запросов параллельно, но ограничена Windows (реестром)

Удаленный запуск сценария в Unix, получить выход локально?

Почему Java не позволяет выбросить проверенное исключение из блока статической инициализации?

Как добавить текстуру для заполнения цветов в ggplot2?

Давайте будем гением компьютера.