Pull to refresh

REST API должен основываться на гипертексте

Reading time6 min
Views7.7K
Original author: Roy T. Fielding
image

– И вы ему поверили? – с упреком сказал уполномоченный по копытам. – Ну, как вы думаете, разве я без вашего разрешения взял бы эти гири?

– Так это вы взяли гири? – закричал Остап. – Зачем же?

– Паниковский сказал, что они золотые.

Остап посмотрел на Паниковского. Только сейчас он заметил, что под его пиджаком нет уже полтинничной манишки и оттуда на свет божий глядит голая грудь. Не говоря ни слова, великий комбинатор свалился на стул. Он затрясся, ловя руками воздух. Потом из его горла вырвались вулканические раскаты, из глаз выбежали слезы, и смех, в котором сказалось все утомление ночи, все разочарование в борьбе с Корейко, так жалко спародированной молочными братьями.

Этим фрагментом из классики я хотел бы предварить перевод блог-поста Роя Т. Филдинга REST APIs must be hypertext-driven. Отдельное спасибо habr.com/users/arthuriantech за ссылку на материал.

Эта неделя на Хабре ознаменовалась как неделя REST(Full) API. Меня в этом смысле всегда смущало наличие приставки REST в этом термине. И, как оказалась, не одного меня. Сегодня я прочитаю сам и предлагаю всем желающим узнать что об этом думал Рой Т. Филдинг в 2008 году. Конечно, кто-то нервно заерзает на стулке и скажет: передайте Рою, Беня знает за REST API. И тем не менее начнем.

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

Что нужно сделать, чтобы они поняли, что в архитектуре REST гипертекст является необходимым элементом? Другими словами, если механизм состояния приложения (и, следовательно, API) не основан на гипертексте, он не может быть RESTful и не может быть REST API. Точка. Какую книгу нужно переписать, чтобы это стало понятным?

Разработчики API, обратите внимание на следующие правила, прежде чем называть свои творения REST API:

API REST не должен зависеть от конкретного протокола связи, хотя его успешное сопоставление с данным протоколом может зависеть от доступности метаданных, выбора методов и т. д. В общем, любой протокол в схеме URI, должен позволять любой схеме URI, быть использованной для идентификации. [Ошибка здесь заключается в том, что идентификация не отделена от взаимодействия.]

API REST не должен содержать каких-либо изменений в протоколах связи, кроме заполнения или исправления деталей недостаточно определенных битов стандартных протоколов, таких как метод PATCH HTTP или поле заголовка Link. Обходные пути для неработающих реализаций (например, таких браузеров, которые достаточно глупы, чтобы полагать, что HTML определяет набор методов HTTP) должны определяться отдельно или, по крайней мере, в приложениях, с ожиданием того, что обходной путь в конечном итоге устареет. [Ошибка здесь заключается в том, что интерфейсы ресурса являются специфическими, а не универсальными.]

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

API REST не должен определять фиксированные имена ресурсов или пространств имен (жесткая связанность клиента и сервера). Серверы должны иметь свободу управления своими собственными пространствами имен. Вместо этого позвольте серверам инструктировать клиентов о том, как создавать соответствующие URI, например, в HTML-формах и шаблонах URI, определяя эти инструкции в типах мультимедиа и ссылочных отношениях. [Ошибка здесь заключается в том, что структура ресурса задается вне этого ресурса, например, в специфичном для предметной области стандарте, что фактически является аналогом функциональной связи RPC].

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

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

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

Этот пост Роя Т. Филдинга вызвал дискуссию в комментах. Предлагаю ознакомиться с частью дискуссии, которая сопровождалась ответами автора.

Вопрос:

В каком смысле вы используете здесь термин «гипертекст»? Должен ли я прочитать Ваши работы, чтобы понять, что Вы имеете в виду, или есть что-то в сети, раскрывающее смысл этого понятия?


Ответ:

У меня есть слайд в моем выступлении REST, в котором объясняется, что означает гипертекст (и гипермедиа).

Гипертекст имеет много определений:

Первоначальное определение Теда Нельсона было сосредоточено на нелинейных документах.

Под «гипертекстом» я подразумеваю нелинейный документ — текст, который разветвляется и позволяет читателю делать выбор, документ, удобный для чтения на интерактивном экране. Как принято считать, это последовательность текстовых блоков, связанных ссылками, которые предлагают читателю различные маршруты. [Теодор Х. Нельсон]


Позднее гипертекст стал ассоциироваться с определенным механизмом пользовательского интерфейса.

Гипертекст является поддерживаемым компьютером носителем информации, в которой взаимосвязанные документы отображаются со своими ссылками на экране компьютера с высоким разрешением. [Джеффри Конклин]


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

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


Dave Johnson (автор подвергшегося критике API):

Пожалуй, я привел нечеткую формулировку. Я никогда не хотел утверждать, что API-интерфейсы OpenSocial или SocialSite RPC были RESTful. Больше на моем блоге rollerweblogger.org/roller/entry/the_x_rated_socialsite_api.


Ответ:

Протокол OpenSocial RESTful не является RESTful. Это можно исправить сравнительно небольшими изменениями, но сейчас это просто упаковка результатов RPC в распространенные типы веб-медиа.

Настоящий RESTful API выглядит как гипертекст. Каждая адресуемая единица информации несет адрес, либо явно (например, атрибуты link и id), либо неявно (например, полученный из определения типа носителя и структуры представления). Результаты запроса представлены списком ссылок со сводной информацией, а не массивами представлений объектов (запрос не заменяет идентификацию ресурсов). Представления ресурсов являются самодокументированными: клиенту не нужно знать, является ли этот ресурс OpenSocialist, потому что он просто воздействует на полученные представления.

Думайте об этом с точки зрения Интернета. Сколько веб-браузеров знают о различии между ресурсом онлайн-банкинга и ресурсом Wiki? Ни один из них. Им не нужно знать о типах ресурсов. То, что им нужно знать — это потенциальные переходы состояний: ссылки и формы, и какая семантика или действие подразумевается при обходе этих ссылок. Браузер представляет их как отдельные элементы управления пользовательского интерфейса, чтобы пользователь мог видеть потенциальные переходы и предвидеть эффект выбранных действий. Боты могут следовать за ними в той степени, если известно, что действия безопасны. Типизированные отношения, конкретные типы носителей и элементы, относящиеся к конкретным действиям, обеспечивают руководство, необходимое для автоматизированных агентов.


Полезные ссылки:
1. Версия перевода от habr.com/ru/users/arthuriantech

2. Тот самый диссер старины Роя
Tags:
Hubs:
Total votes 16: ↑10 and ↓6+4
Comments22

Articles