Today REST is the most commonly used word when talk comes to web API. But how really good is the idea of RESTful APIs? Is this a silver bullet or a big lie? Come and join the session to take a deep dive and to find the answer.
2. Архитектурный стиль
Легче SOAP
Всё есть ресурс
Определен Роем Филидингом в 2000г.
Разрабатывался параллельно с HTTP 1.1 1996–1999
На данный момент является доминирующим стилем при создании HTTP API
Representational State Transfer
3. • Клиент-серверная архитектура
• Система слоев
• Кеширование
• Отсутствие состояния
• Унифицированный интерфейс
REST Architectural constraints
5. • Управление через представление
• Само-описываемые сообщения
• Гипермедиа как средство состояния приложения (HATEOAS)
• Идентификация ресурсов
Uniform interface
7. Метод HTTP URI Коллекция URI Ресурс
CREATE POST
/api/companies /api/companies/{id}
READ GET
UPDATE PUT
DELETE DELETE
RESTful HTTP Web API
8. • На момент создания идентификатор не известен
POST /api/companies/23
{“name”: ”contoso”}
• Создаем ресурс или коллекцию ресурсов?
POST /api/companies
{“name”: ”contoso”}
• Можно удалить коллекцию или заменить все значения, но не создать
CREATE
9. • механизм запросов не предусмотрен
• поддержка тела запроса с методом GET не определена стандартом HTTP
GET /api/companies?namelike=cikl&location=odessa
• OData еще один механизм со своими проблемами
GET /api/companies/1/employees?$filter=Gender eq
MS.OData.Service.Sample.TrippinInMemory.Models.PersonGender’male'
READ
10. • PUT предполагает передачу всего содержимого объекта
PUT /api/companies
{“name“: “Contoso“}
• PATCH изначально не поддерживался, проблема с интерпретацией обнуления
PATCH /api/companies
{“location“: “Ukraine“, “name”: null}
UPDATE
11. • Вроде все должно быть просто
DELETE /api/items/23
• Есть проблемы с поддержкой метода
POST /api/items/23/delete
• Метод не поддерживает тела запроса
POST /api/items/delete?ids=23,24,25
DELETE
12. • Гарантированная поддержка GET и POST – безопасные методы
• Нет возможности расширения
• в бизнес решениях не только CRUD операции
GET /api/company/2/offices/3/showroom
GET /api/company/2/offices/3?action=showRoom
HTTP Methods
13. • Порядка 70 официальных и 20 не официальных кодов
• HTTP накладывает ограничения на коды
• Не всегда понятно как интерпретировать коды
• Приходится дополнять ответ статус кодом
HTTP/1.1 200 OK
Content-Type: application/json
{“result“: “Transaction Complete”}
HTTP Status Codes
15. Чему отдать приоритет когда ресурсы равнозначны
GET /api/beer/2/company/3/beer/2
или
GET /api/company/3/beer/2/company/3
Many to Many
16. • Все сущности в коллекции
GET /api/company/
GET /api/company/1
GET /api/company/N+1
• Сущность и все вложенные сущности
GET /api/company/1
GET /api/company/1/offices
GET /api/company/1/customers
GET /api/company/1/something-other
N+1
19. Реализация завязывается на протокол
HTTP имеет серьезные ограничения
Нет возможности изменить протокол
ISO/OSI Violation
20. Слой Название
Service API
7 Application HTTP
6 Presentation ASCII
5 Session
4 Transport TCP
3 Network IP
2 Data Link IEEE 802.3/802.2
1 Physical
OSI Tier 7
передача/изменения состояния через представления - кто сразу понял что это такое ?)
это СТИЛЬ!определён в 2000 годуочевидно оказало влияние то что Рой в это же время разрабатывал стандарт HTTP 1.1
на данный момент доминирующий стиль, не могут же все ошибаться? Или могут ?) вспомнить что 50 лет назад все думали что курить полезно :)
Существует шесть фактически пять обязательных ограничений для построения распределённых REST-приложений по Филдингу
Модель клиент-сервер. Отделение потребности интерфейса клиента от потребностей сервера, хранящего данные, повышает переносимость кода клиентского интерфейса на другие платформы, а упрощение серверной частиулучшает масштабируемость.
Слои - клиент обычно не способен точно определить, взаимодействует ли он напрямую с сервером или же с промежуточным узлом, в связи с иерархической структурой сетей (подразумевая, что такая структура образует слои). Применение промежуточных серверов способно повысить масштабируемость за счет балансировки нагрузки и распределенного кэширования.
Кэширование - ответы сервера, в свою очередь, должны иметь явное или неявное обозначение как кэшируемые или некэшируемые с целью предотвращения получения клиентами устаревших или неверных данных в ответ на последующие запросы
Отсутствие состояния. В период между запросами клиента никакая информация о состоянии клиента на сервере не хранится.
Наличие унифицированного интерфейса является фундаментальным требованием дизайна REST-сервисов. Унифицированные интерфейсы позволяют каждому из сервисов развиваться независимо. К унифицированным интерфейсам предъявляются следующие четыре ограничительных условия
A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way. Intermediary servers may improve system scalability by enabling load balancing and by providing shared caches. They may also enforce security policies.
К унифицированным интерфейсам предъявляются следующие четыре ограничительных условия
Каждый ресурс должен быть уникально обозначен постоянным идентификатором.
«Само-описываемые» сообщения - Каждое сообщение содержит достаточно информации, чтобы понять каким образом его обрабатывать.
Гипермедиа — это пафосное понятие для обозначения данных, которые содержат информацию о том, что клиенту нужно делать дальше, другими словами, какие еще запросы он может сделать
Идентификация ресурсов — Все ресурсы идентифицируются в запросах, например, с использованием URI в интернет-системах.
На той же Wikipedia описывается возможность удалить всю коллекцию или заменить значения всей коллекции
Но почему то нельзя создать коллекцию
По причине того что механизм запроса ресурсов не предусмотрен – каждый пилит как хочет
Например тот же Lucen который интерпретирует что можно запрос вставлять в тело HTTP запроса
Семантика метода POST требует передачи всего содержимого изменяемого объекта. На первый взгляд это упрощает реализацию, но только до того момента, как размер объектов вдруг начинает превышать 4Кб и количество операций изменения превышает 100 запросов в секунду. После этого разработчик хватается за голову и начинает реализовывать дополнительные методы частичного редактирования. Что вновь нарушает логику REST.
Возможное решение проблемы полного редактирования предлагает спецификация RFC5789 PATCH Method for HTTP.
Она была разработана в 2010 году. Учитывая занятость разработчиков браузеров реализацией поддержки HTML5, вряд ли PATCH получит широкое распространение в ближайшее время. RFC5789 вводит еще один HTTP-метод, а значит еще один REST-глагол, область применения которого пересекается с POST, PUT и частично DELETE. Структура PATCH конструкций значительно более сложна и громоздка по сравнению с остальными HTTP-методами.
В реальных бизне срешениях нет операции удаленияПопробуйте реализовать пакетное удаление.
Поскольку HTML4 и XHTML1 требовали обязательной поддержки только GET и POST большинство разработчиков браузеров и не заморачивались реализацией всех остальных методов. Соответственно, единственный гарантированный способ поддерживать другие метода — добавление поля с именем метода в POST запрос, что опять-таки нарушает логику REST.
Например, когда мы должны использовать код 200 ОК? Можем ли мы использовать его для подтверждения успешного апдейта записи, или нам стоит использовать код 201 Created? Судя по всему, нужно использовать код 250 Updated, однако его не существует. И еще, кто-нибудь может объяснить что означает код 417 Expectation failed?! Кто-нибудь кроме Роя, конечно.
Словарь HTTP методов и кодов слишком расплывчатый и неполный, чтобы прийти наконец к единым определениям. Нет никого, если я не ошибаюсь, кто нашел единый, общий порядок и призвал остальных его соблюдать. То, что подразумевается под 200 ОК в одной компании может обозначать вовсе иную информацию в другой, что делает обсуждаемую технологию непредсказуемой.
Ситуация с кодами ответа не лучше. Разные браузеры (и серверные приложения тоже) часто понимают эти коды по-разному. Например, получив код 307 Temporary redirect, один браузер может позволить пользовательскому скрипту рассмотреть этот ответ и отменить действие до его выполнения. Другой браузер может просто напросто запретить скрипту делать что-либо. На самом деле, единственными кодами, обработки которых можно не бояться, являются 200 ОК и 500 Internal server error. В остальных же случаях поддержка ответов варьируется от «довольно хорошей» до «просто ужасной». Именно по-этому нам часто приходится дополнять тело ответа кодом, который мы на самом деле подразумевали.
Даже если мы всё же смогли бы согласовать всё вышеописанное, а еще магическим образом пофиксили всё подключённое к интернету, но не приспособленное к REST программное обеспечение — мы всё равно столкнёмся с очередной проблемой.
С сервера посылать запрет кеширования.
К каждому запросу подсовывать рандомную строку
Переделать API так, чтобы в нём участвовала рандомная строка
Делать POST, а потом GET - очень глупо, медленно, неудобно, но семантично
REST API представляет собой набор точек назначения, каждая из которых соответствует ресурсу.Если необходимо получить сложное представление состоящие из множества ресурсов или коллекцию ресурсов.
приходится делать множество запросов, чтобы собрать все необходимые данные.
RESTful API в дребезги разбивает один из фундаментальных законов о хорошей связи: содержимое сообщения должно быть абсолютно независимо от канала передачи. Их смешивание — это путь к сплошной путанице.
Постоянное переплетение HTTP протокола и передаваемой информации полностью лишает нас возможности переноса RESTful API на другие каналы связи. Портирование RESTfulAPI с HTTP на какой-либо другой протокол передачи данных требует полного распутывания и реструктуризации информации из семи разных точек, о которых мы говорили ранее.
Сетевая модель OSI (англ. open systems interconnection basic reference model — Базовая Эталонная Модель Взаимодействия Открытых Систем (ЭМВОС))
протокол удалённого вызова процедур, использующий JSON для кодирования сообщений. Это очень простой протокол (очень похожий на XML-RPC), определяющий только несколько типов данных и команд. JSON-RPC поддерживает уведомления (информация, отправляемая на сервер, не требует ответа) и множественные вызовы.
Все передаваемые данные — простые объекты, сериализованные в JSON[3]. Запрос — вызов определённого метода, предоставляемого удалённой системой. Он должен содержать три обязательных свойства:
method — Строка с именем вызываемого метода.
params — Массив объектов, которые должны быть переданы методу, как параметры.
id — Значение любого типа, которое используется для установки соответствия между запросом и ответом.
Сервер должен отослать правильный ответ на каждый полученный запрос. Ответ должен содержать следующие свойства:
result — Данные, которые вернул метод. Если произошла ошибка во время выполнения метода, это свойство должно быть установлено в null.
error — Код ошибки, если произошла ошибка во время выполнения метода, иначе null.
id — То же значение, что и в запросе, к которому относится данный ответ.
протокол удалённого вызова процедур, использующий JSON для кодирования сообщений. Это очень простой протокол (очень похожий на XML-RPC), определяющий только несколько типов данных и команд. JSON-RPC поддерживает уведомления (информация, отправляемая на сервер, не требует ответа) и множественные вызовы.
Все передаваемые данные — простые объекты, сериализованные в JSON[3]. Запрос — вызов определённого метода, предоставляемого удалённой системой. Он должен содержать три обязательных свойства:
method — Строка с именем вызываемого метода.
params — Массив объектов, которые должны быть переданы методу, как параметры.
id — Значение любого типа, которое используется для установки соответствия между запросом и ответом.
Сервер должен отослать правильный ответ на каждый полученный запрос. Ответ должен содержать следующие свойства:
result — Данные, которые вернул метод. Если произошла ошибка во время выполнения метода, это свойство должно быть установлено в null.
error — Код ошибки, если произошла ошибка во время выполнения метода, иначе null.
id — То же значение, что и в запросе, к которому относится данный ответ.