Что такое REST

Архитектурный стиль, на котором держится современный веб - и который чаще всего объясняют неправильно

Что такое REST.md

Содержание


Коротко и чётко

REST (Representational State Transfer) - это архитектурный стиль для проектирования распределённых систем. Описан Роем Филдингом в докторской диссертации в 2000 году.

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

  • Client-Server - клиент и сервер разделены и независимы друг от друга
  • Stateless - каждый запрос самодостаточен, сервер не хранит состояние клиента
  • Cacheable - ответы сервера могут кэшироваться на стороне клиента
  • Uniform Interface - единый стандартизированный интерфейс взаимодействия
  • Layered System - между клиентом и сервером может быть несколько слоёв
  • Code on Demand - необязательный, сервер может передавать исполняемый код клиенту

REST - это архитектурный стиль, не протокол. Описан Филдингом в 2000 году как обобщение принципов, на которых уже работал HTTP и весь веб. Шесть ограничений: разделение клиента и сервера, stateless - сервер не помнит предыдущих запросов, кэшируемость, единый интерфейс, слоистая архитектура и опциональная передача кода. Соблюдение этих принципов даёт масштабируемость, простоту и независимость компонентов системы.


Простыми словами

Представь, что ты звонишь на горячую линию банка.

Каждый раз, когда ты звонишь, тебя соединяют с новым оператором. Этот оператор ничего не знает о твоих прошлых звонках. Тебе нужно каждый раз называть своё имя, номер карты и объяснять проблему заново. Это неудобно для тебя - но очень удобно для банка: он может нанять тысячу операторов, и любой из них справится с твоим запросом, потому что вся нужная информация есть в самом звонке.

Вот как примерно работает REST.

Клиент - это ты. Сервер - это банк. Каждый запрос - это звонок. Сервер не помнит тебя между запросами. Зато система легко масштабируется и любой сервер может обработать любой запрос.


Шесть принципов с примерами


1. Client-Server - клиент и сервер живут отдельно

Клиент отвечает за интерфейс - то, что видит пользователь. Сервер отвечает за данные и логику. Они общаются через чётко определённый канал и не знают, как устроены друг у друга изнутри.

Это значит: можно полностью переписать фронтенд с React на Vue - сервер не заметит. Можно переехать с MySQL на PostgreSQL - клиент не заметит. Каждый развивается независимо.


2. Stateless - сервер ничего не помнит

Это самый важный принцип. Каждый HTTP-запрос должен содержать всё, что нужно серверу для его обработки. Сервер не хранит никакой информации о клиенте между запросами - ни сессии, ни истории.

Хочешь авторизоваться? Передавай токен в каждом запросе. Нужно знать, кто ты? Напиши об этом в самом запросе.

Зачем это нужно: если сервер не хранит состояние - можно поднять десять одинаковых серверов, и любой обработает любой запрос. Горизонтальное масштабирование становится тривиальным.


3. Cacheable - ответы можно кэшировать

Сервер может пометить ответ как кэшируемый. Тогда клиент сохранит его и при следующем таком же запросе не пойдёт на сервер - возьмёт из кэша.

Например, список стран мира не меняется каждую минуту. Сервер возвращает его с заголовком Cache-Control: max-age=86400 - и клиент следующие 24 часа не будет запрашивать его снова. Это снижает нагрузку на сервер и ускоряет ответ для клиента.


4. Uniform Interface - единый способ общения

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

  • Ресурсы - всё, с чем работаем, идентифицируется через URL (/users, /articles/1)
  • Представления - данные передаются в стандартном формате (JSON, XML)
  • Самоописание - каждое сообщение содержит достаточно информации для своей обработки (Content-Type, статус-коды)

5. Layered System - между клиентом и сервером могут быть слои

Клиент не знает, с кем именно он общается. Между ним и конечным сервером может быть балансировщик нагрузки, прокси, CDN, шлюз безопасности - что угодно. Клиент видит только один адрес и получает ответ. Что происходит за кулисами - его не касается.

Это позволяет добавлять промежуточные слои не меняя ни клиент, ни сервер.


6. Code on Demand - необязательный принцип

Сервер может передавать клиенту исполняемый код. Например, JavaScript-файл, который браузер скачает и выполнит. В API-разработке этот принцип почти не используется, но он часть оригинальной спецификации.


Глубже

REST описывает уже существующий веб. Рой Филдинг был одним из авторов спецификации HTTP/1.1. Когда он писал диссертацию - он не придумывал новую архитектуру, а анализировал и формализовал принципы, на которых уже работал HTTP и весь интернет. REST - это в каком-то смысле «почему HTTP устроен именно так».

Stateless - это компромисс. Отсутствие состояния на сервере упрощает масштабирование, но усложняет жизнь разработчику. Куки, серверные сессии, «помни меня» - всё это удобно для пользователя, но нарушает stateless. Поэтому индустрия выработала компромисс: токены (JWT и другие), которые хранятся у клиента и передаются в каждом запросе. Сервер stateless, но клиент несёт своё состояние с собой.

REST - не единственная архитектура. До REST доминировал SOAP - жёсткий протокол с XML-конвертами и строгим контрактом. После REST появился GraphQL от Facebook - один endpoint, клиент сам описывает нужные данные. Есть gRPC от Google - бинарный протокол, очень быстрый, популярен для внутренних микросервисов. REST занял доминирующее положение в публичных API благодаря простоте и использованию стандартного HTTP.

Большинство «REST API» не являются настоящим REST. Филдинг об этом неоднократно писал публично и раздражался. Главный нарушаемый принцип - HATEOAS: в ответе должны быть ссылки на связанные ресурсы и доступные действия. Почти никто этого не делает. Индустрия де-факто приняла упрощённую версию, и это нормально - но называть её «REST» строго говоря неточно.


FAQ

REST - это протокол? Нет. REST - архитектурный стиль, набор ограничений. Протокол - это HTTP. REST описывает как использовать HTTP правильно, но сам по себе не является протоколом. Можно реализовать REST поверх других протоколов, хотя на практике это редкость.
Зачем stateless, если это неудобно? Stateless делает систему горизонтально масштабируемой. Если сервер не хранит состояние клиента, можно поднять сто одинаковых серверов и любой обработает любой запрос. Если бы состояние хранилось на сервере, клиент был бы привязан к конкретному серверу - это называется «липкая сессия» и это проблема при масштабировании.
Кто такой Рой Филдинг? Один из авторов спецификации HTTP/1.1 и URI. Описал REST в своей докторской диссертации в Калифорнийском университете в 2000 году. Позже работал в Adobe. Периодически пишет в блоге, что большинство API неправильно называют себя REST.
Чем REST отличается от HTTP? HTTP - это протокол передачи данных, набор правил как именно передаются байты по сети. REST - это архитектурный стиль, описывающий как проектировать систему. REST использует HTTP как транспорт, но сам HTTP существует независимо от REST. Можно использовать HTTP без REST - например, передавать по нему SOAP-сообщения.
Что такое «представление ресурса»? Ресурс - это абстракция (пользователь, статья, заказ). Представление - это конкретная форма, в которой ресурс передаётся клиенту. Один и тот же ресурс «пользователь» может быть передан как JSON, XML или HTML - в зависимости от того, что запросил клиент через заголовок `Accept`. Сам ресурс на сервере при этом один.