Статьи

REST не об API-интерфейсах (часть 1)


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

Отдых не об API, Часть 1: Описание REST и представление, ориентированное на API

Отдых не об API, Часть 2: Истинная сила REST, и примеры его применения

Краткое описание ОТДЫХА

REST (сокращение от REpresentational State Transfer) — это архитектурный стиль, который описывает, как работает распределенная гипермедиа система. Интернет (или «сеть») является наиболее известным примером распределенной гипермедиа системы. Термин REST был введен Роем Филдингом. Его докторская диссертация [1] остается основным источником информации о REST, которую я кратко изложил ниже.

REST описывается с использованием 6 архитектурных ограничений, 4 интерфейсных ограничений и 3 архитектурных компонентов.

Архитектурные ограничения

  1. Клиент-сервер : разделение ролей клиента и сервера, т.е. представление ресурсов из их сохраненного состояния.
  2. Без сохранения состояния: сервер не должен хранить или кэшировать состояние клиента между запросами. Каждый клиентский запрос должен переводить сохраненные данные из одного допустимого состояния в другое. Это позволяет использовать любой доступный экземпляр сервера для выполнения любого запроса.
  3. Кэш : сервер должен указывать, могут ли данные кэшироваться и использоваться повторно в разных запросах.
  4. Единый интерфейс : все данные сервера могут обрабатываться с использованием одного и того же интерфейса. Это ограничение дополнительно расширяется на четыре ограничения интерфейса:

    1. идентификация ресурсов : все ресурсы имеют одно или несколько имен (например, HTTP URI), управляемых полномочиями по именованию (обычно сервером).
    2. манипулирование ресурсами с помощью представлений : представление ресурса отделено от его идентификации и может изменяться со временем.
    3. самоописательные сообщения : сообщения должны содержать метаданные, описывающие, как читать сообщения (например, типы HTTP MIME и другие заголовки).
    4. гипермедиа как движок состояния приложения (HATEOS) : представления также должны содержать данные для управления состоянием приложения. Это позволяет клиентам слабо связываться с серверами и не требует предварительных (жестко закодированных) знаний о том, как взаимодействовать с конкретным ресурсом.
  5. Слоистая система : каждый слой имеет дело с тем, что под ним, и не имеет прямой видимости для других слоев.
  6. Код по требованию (необязательно) : сервер может расширить функциональность клиента, отправив обратно сценарии или код.

Архитектурные элементы

  • Элементы данных : элементы данных позволяют перемещать информацию из того места, где она хранится, в место, где она будет использоваться. Элементы данных описываются Ресурсами, Идентификаторами Ресурсов и Представлениями.

    1. Ресурсы : вещи с уникальными именами (например, HTML-страница или изображение в Интернете или экземпляр объекта в приложении.) Запрос на ресурс может вернуть представление или набор идентификаторов ресурса или комбинацию два.
    2. Идентификаторы ресурса : это имена, данные ресурсам (например, HTTP URL).
    3. Представления : представление — это то, что передается между компонентами REST.
  • Соединители : соединители инкапсулируют действия доступа к ресурсам и передачи представлений.

    1. Клиент : Клиент инициирует запросы на информацию.
    2. Сервер : сервер прослушивает и отвечает на запросы
    3. Кэш : кэш может быть присоединен к клиентам или серверам и используется для ускорения взаимодействия.
    4. Resolver : Resolver помогает найти ресурсы для установления межкомпонентной связи (например, привязка DNS)
    5. Туннель : Туннель позволяет взаимодействовать через сетевые границы, как брандмауэры.
  • Компоненты : компоненты — это разные роли в системе. Компоненты используют один или несколько соединителей для взаимодействия с другими компонентами.

    1. Исходный сервер : использует серверный соединитель для управления коллекцией ресурсов.
    2. Шлюз : компонент шлюза является обратным прокси. Он выполняет общие функции на разных серверах, такие как аутентификация.
    3. Прокси : прокси — это промежуточный компонент, выбранный клиентом для выполнения общих функций.
    4. Пользовательский агент : использует клиентские соединители для инициирования запросов и получения представлений ресурсов от серверов.

API-ориентированный вид REST

Ориентированное на API представление REST фокусируется только на единообразных интерфейсных ограничениях. В большинстве случаев, когда обсуждаются API-интерфейсы, предполагается, что это внешние API-интерфейсы (ориентированные на север с точки зрения приложения). Внешний API-интерфейс RESTful является хорошим дополнением для программных продуктов и может удовлетворить потребности бизнеса. Тем не менее, он не учитывает ремонтопригодность продукта и другие архитектурные проблемы, такие как эластичность, упругость и возможность комбинирования.

Модель зрелости Ричардсона (RMM) [2] является популярным способом измерения того, насколько RESTful является API. RMM полезен для определения, имеет ли API характеристики REST, но не подразумевает систему RESTful. В блоге, описывающем RMM [3] , Мартин Фаулер отмечает:

«Я должен подчеркнуть, что RMM, хотя и хороший способ думать о том, что такое элементы REST, не является определением уровней самого REST. Рой Филдинг ясно дал понять, что уровень 3 RMM является предварительным условием ОТДЫХА . Как и многие термины в программном обеспечении, REST получает множество определений, но, поскольку Рой Филдинг придумал этот термин, его определение должно иметь больший вес, чем большинство ». — Мартин Фаулер, модель зрелости Ричардсона

(См. [4] для сообщения Роя Филдинга, на которое ссылается Мартин.)

Большинство реализаций API RESTful, размещенных поверх существующих систем, испытывают трудности с ограничением интерфейса HATEOS. Они заканчивают тем, что приняли «прагматический ОТДЫХ» [5] . Чтобы правильно установить ограничение HATEOS, необходимо, чтобы сервер и клиент были разработаны для такого типа взаимодействия, как веб-браузер и веб-сервер.

Если вы пытаетесь добавить RESTful API в существующее приложение, это будет трудно сделать. Однако, если вы можете спроектировать для HATEOS, потенциальный выигрыш огромен, так как у вас будет слабосвязанная система, где изменения на стороне сервера не могут легко сломать клиента. [6] 

Резюме

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

Рекомендации

[1] Representational State Transfer (REST), Roy Fielding, http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
[2] Richardson Maturity Model, Leonard Richardson Presentation 2008, http://www.crummy.com/writing/speaking/2008-QCon/act3.html
[3] Richardson Maturity Model, Martin Fowler, http://martinfowler.com/articles/richardsonMaturityModel.html
[4] REST APIs must be hypertext-driven, Roy Fielding, http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
[5] API Design: Harnessing HATEOAS, Part 2, https://blog.apigee.com/detail/api_design_harnessing_hateoas_part_2
[6] Haters gonna HATEOAS, http://timelessrepo.com/haters-gonna-hateoas