HATEOAS: реализация функций в RESTful API

Я не знаю кто и когда придумал аббревиатуру HATEOAS, означающую Hypermedia As The Engine Of Application State. Выглядит она страшно, а звучит непонятно. В общем разбираться с тем что это такое и зачем оно нужно совершенно не хочется. Из-за этого потенциал, заложенный в архитектурный стиль REST и позволяющий создавать довольно интересные программные интерфейсы остается не раскрытым. Но обо всем по порядку.

В 2000 году Рой Филдинг (Roy Fielding) написал диссертацию  “Architectural Styles and the Design of Network-based Software Architectures” в пятой главе которой представил архитектурный стиль Representational State Transfer (REST). Для того, чтоб объяснить, что же это такое, чем в его понимании является архитектура и архитектурный стиль он написал предыдущие четыре главы. Выглядят его рассуждения об архитектуре вообще и описываемом архитектурном стиле в частности довольно громоздко. Так архитектурный стиль REST описывается Филдингом в виде набора ограничений на поведение компонентов системы, выстраиваемых посредством следующих шагов:

  1. Starting with the Null Style
  2. Client-Server
  3. Stateless
  4. Cache
  5. Uniform Interface
  6. Layered System
  7. Code-On-Demand

Так как все разработчики нормальные люди, то читать эту диссертацию естественно никто не стал. Когда же REST API стали приобретать популярность, то любой программный интерфейс, реализованный непосредственно поверх протокола HTTP и использующий XML, а позднее и JSON для представления данных стали называть REST-ом. Рой, конечно, пытался было объяснить людям, что он имел в виду нечто иное. См., например, REST APIs must be hypertext-driven:

I am getting frustrated by the number of people calling any HTTP-based interface a REST API. Today’s example is the SocialSite REST API. That is RPC. It screams RPC

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

Не всем и не всегда хватит смелости сказать прямо в лицо ИТ-руководителю, что он говорит полную ерунду. Поэтому, чтоб не называть уважаемых людей идиотами, лучше воспользоваться так называемой моделью зрелости REST API, предложенной Леонардом Ричардсоном (см. Justice Will Take Us Millions Of Intricate Moves). Суть предложения Ричардсона в том, чтоб практически любые программные интерфейсы, реализованный поверх протокола HTTP называть словом REST, добавляя при этом, что у данных программных интерфейсов могут быть разные уровни зрелости. Нулевой уровень зрелости – «The Swamp of POX». Если разработчик программного интерфейса понимает концепцию Resource и реализует её, то его API приобретает первый уровень зрелости. Правильно использует HTTP методы GET и POST – второй и т.д.

Но перейдем непосредственно к теме Hypermedia Controls (вкратце я пытался изложить это здесь: HATEOAS еще семь лет назад). Вызывая тот или иной REST API приложение получает не только данные о ресурсе – совокупность характеристик в формате ‘ключ=значение’ или даже более сложную структуру, например, в виде JSON дерева, но и набор гиперссылок. Можно считать, что ваше приложение – это конечный автомат. Его состоянием текущим состоянием является URL программного интерфейса, который он только что вызвал, а набором допустимых переходов в другие состояния – множество гиперссылок, полученных в ответе. Каждая полученная гиперссылка – это глагол, именующую соответствующую операцию для перевода вашего приложения в какое-либо другое состояние. Вы можете придумывать для клиентского приложения абсолютно любые операции, например, такие: UpdateSubscriberInformationWithNoLockAtTheEndOfDay. Все безумные методы, реализованные во времена сервис-ориентированной архитектуры в виде SOAP Services, можно сделать подобным способом. Это будет уродливо, но вполне реализуемо. Здесь важно понимать одну вещь RESTful API подразумевает паттерн организации данных Event Sourcing. Вы смотрите на свои данные, как на поток изменений, а не на записи о текущем состоянии объекта. Для каждого вида изменений система реализует отдельную коллекцию ресурсов, в которую приложения такие изменения добавляют (см. рисунок).

Т.е. принципиально возможно каждому ресурсу приписать любой набор коллекций, накапливающих информацию о свершенных с ним операциях. Например, для ресурса http://сервер/кинотеатр/зал1/ряд10/место5 сделать коллекции:

И реализация клиентским приложением любой операции будет заключаться в добавлении в соответствующую коллекцию новой записи. Я правда надеюсь, что сервис бронирования мест создается ответственными профессионалами и четвертую гиперссылку в GET запросе ресурса //зал1/ряд10/место5/ вам никогда не передадут. Впрочем, сервис сам решает какой набор операций передавать каждому конкретному клиентскому приложению. Это может определяться правами доступа или другими соображениями. Более того, принципиально сервис может управлять точками подключения (endpoints). Т.е. для совершения одной и той же операции одним приложениям предавать гиперссылку на один ‘сервер:порт’ а другим совершенно иную гиперссылку на другой сервер. Вся мощь спецификации URI/URL в ваших руках

Из того, что изложенные возможности реализуемы в RESTful API совершенно не следует, что их непременно надо использовать. Какой набор коллекций ресурсов создать, кому и когда предоставлять о них информацию, как распределить обработчики этих команд по узлам сети – это решения архитектора конкретного программного интерфейса. Изобразительных средств для самовыражения предложено достаточно. Остальное вопрос обоснованности потребностей заказчика и наличия вкуса у проектировщика API

HATEOAS: реализация функций в RESTful API: 4 комментария

  1. Но ведь “забронировать” “снять_бронь” “испортить_кресло” это verbs, а не ресурс. И вообще такой подход – суть rpc-style.

    1. Да. И это не хорошо! Но если у нас вагон унаследованных сервисов и годами накопленной бизнес-логики, к которой мы хотим предоставить API, то возможности сделать как-то иначе может не быть. Конечно, количество отглагольных существительных, типа: заказы, резервирования, обращения должно быть разумным

  2. Уведомление: korzhanov.info

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *