REST (REpresentational State Transfer) представляет собой архитектурный стиль, принципы которого направлены на создание распределенных гипермедиа систем, применяемых в World Wide Web. Он предлагает универсальные методы обработки и передачи состояния ресурсов через HTTP. Автор концепции и термина - Рой Филдинг, 2000 г.

В настоящее время REST практически заменил другие подходы, такие как SOAP и WSDL.

Рассмотрим, какие преимущества предлагает REST:

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

Когда следует применять REST:

  • Когда имеются ограничения по пропускной способности соединения;
  • Если необходимо кэшировать запросы для повышения эффективности;
  • В системах, предполагающих значительное масштабирование;
  • В сервисах, использующих AJAX.

Преимущества REST


  • Отсутствие дополнительных прослоек: данные передаются в том виде, каковы они есть, без упаковки в XML или AMF, в отличие от SOAP и Flash.
  • Каждый ресурс четко идентифицируется своим URL, который выступает в качестве первичного ключа. Формат данных по адресу значения не имеет и может быть разным: от HTML до JPEG.
  • Управление данными ресурса осуществляется на основе протокола передачи данных, чаще всего HTTP. В HTTP предусмотрены методы для выполнения действий над данными: GET, PUT, POST, DELETE, позволяющие реализовать операции CRUD (Create-Read-Update-Delete) различной сложностью.

Что такое RESTful?


Для признания системы RESTful, она должна удовлетворять следующим критериям:

  1. Client-Server: Разделение системы на клиенты и серверы. Это обеспечивает независимость клиента от хранения данных и улучшает мобильность кода. Серверы не взаимодействуют с интерфейсом пользователя, что упрощает их конструкцию и масштабируемость.
  2. Stateless: Сервер не хранит информацию по клиентам. В запросе должна содержаться вся необходимая информация для его обработки и идентификации клиента.
  3. Cache: Кэширование ответов обязательно, чтобы предотвратить использование клиентами некорректных данных в будущем.
  4. Uniform Interface: Унифицированный интерфейс, обеспечивающий надежную связь между клиентами и серверами, подчеркивается четырьмя ключевыми принципами:

    Эти принципы включают:

    • Ресурсная идентификация: в REST ресурсом считается все, что можно назвать. Каждый ресурс должен иметь стабильный идентификатор, иначе идентификатор, не зависящий от состояния ресурса, выражается URI.
    • Манипуляция ресурсами через представления: Представление позволяет работать с ресурсом, показывая его текущее или желаемое состояние, скажем, в форме XML или HTML.
    • Самодокументируемые сообщения: Все нужные данные содержатся в запросе и ответе, исключая дополнительные сообщения или кэши, важное условие для масштабируемой системы.
    • HATEOAS: Использует гипермедиа для отображения состояния приложения, ссылки в ответе помогают управлять URI и сделают его самоописанием.
  5. Layered System: Позволяет деление системы на иерархические слои, где каждый элемент взаимодействует исключительно со следующим близким уровнем.
  6. Code-On-Demand (опционально): Возможность загрузки и выполнения кода на клиентской стороне для расширения функциональности.

Это подразумевает, что сервер временно может передать клиенту исполняемую логику или программу для повышения функциональности, например, в виде Java-апплетов или скриптов JavaScript.

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


Идемпотентность


Под идемпотентностью операции в RESTful-сервисе понимается возможность повторного выполнения одного и того же запроса без изменения результата на сервере. То есть, многократные идентичные запросы эквивалентны одному. Обратите внимание, что хотя идемпотентные операции имеют один и тот же результат на сервере, ответы могут различаться, например, если состояние ресурса изменилось между запросами.

Методы PUT и DELETE по умолчанию считаются идемпотентными. Однако будьте внимательны с методом DELETE, так как успешный запрос DELETE вернет статус 200 (OK) или 204 (No Content), но при последующих обращениях будет возвращен статус 404 (Not Found). Хотя состояние на сервере будет оставаться неизменным, ответы могут различаться.

Методы GET, HEAD, OPTIONS и TRACE определены как безопасные. Эти методы предназначены исключительно для получения информации, не изменяют состояние сервера и не вызывают побочных эффектов, кроме безвредных, таких как: ведение логов, кеширование, показ баннерной рекламы или увеличение счётчиков.

Безопасные операции считаются автоматически идемпотентными, так как не модифицируют серверное состояние. Следует помнить, что безопасность не гарантирует одинаковость возвращаемых результатов при каждом запросе.


HTTP методы для создания RESTful сервисов


HTTP метод GET используется для извлечения или чтения ресурсов. Успешное выполнение запроса GET возвращает ресурс в формате XML или JSON с кодом состояния HTTP 200 (OK). В противном случае могут быть возвращены коды 404 (NOT FOUND) или 400 (BAD REQUEST).

  • GET http://www.example.com/api/v1.0/users (получить список пользователей)
  • GET http://www.example.com/api/v1.0/users/12345 (получить информацию о пользователе с id 12345)
  • GET http://www.example.com/api/v1.0/users/12345/orders (получить список заказов пользователя с id 12345)

HTTP метод PUT чаще всего применяется для обновления ресурса. При отправке PUT-запроса нужно передать обновленные данные ресурса, соответствующего указанному URI.

Для создания ресурсов предпочтительно использовать POST. В этом случае POST предоставляет новому ресурсу соответствующий идентификатор.

Успешный PUT-запрос возвращает код 200 (или 204 при отсутствии содержимого ответа). Несмотря на ненадежность, метод PUT является идемпотентным: повторяющиеся запросы PUT к одному и тому же URI не изменяют общее состояние системы.

  • PUT http://www.example.com/api/v1.0/users/12345 (обновить информацию о пользователе с id 12345)
  • PUT http://www.example.com/api/v1.0/users/12345/orders/98765 (обновить информацию о заказе с id 98765 для пользователя с id 12345)

HTTP метод POST обычно используется для создания новых ресурсов. Он отправляет данные к родительскому ресурсу, создавая вложенные ресурсы в системе, и при этом сервис отвечает за установление связи с родительским ресурсом и назначение нового ID.

При успешном создании возвращается код HTTP 201, а в заголовке `Location` указывается адрес созданного ресурса.

POST не гарантирует идемпотентности и является небезопасным. Следовательно, его используют для неидемпотентных операций.

  • POST http://www.example.com/api/v1.0/customers (создать новый ресурс в разделе customers)
  • POST http://www.example.com/api/v1.0/customers/12345/orders (создать заказ для ресурса с id 12345)

HTTP метод DELETE предназначен для удаления ресурсов, идентифицируемых указанным URI (ID).

Успешное выполнение запроса DELETE возвращает код HTTP 200 (OK) с данными удаленного ресурса или 204 (NO CONTENT) без тела ответа. Хотя DELETE считается идемпотентным методом в спецификации HTTP, повторный запрос может вернуть 404 (NOT FOUND), если ресурс уже удален, что не изменяет состояние сервера, но отличаются ответы.

  • DELETE http://www.example.com/api/v1.0/customers/12345 (удалить из customers ресурс с id 12345)
  • DELETE http://www.example.com/api/v1.0/customers/12345/orders/21 (удалить у ресурса с id 12345 заказ с id 21)

Коды состояния HTTP


Код состояния HTTP отражает, был ли запрос обработан успешно. Коды делятся на пять основных категорий:

  1. Информационные 100 - 199
  2. Успешные 200 - 299
  3. Перенаправления 300 - 399
  4. Клиентские ошибки 400 - 499
  5. Серверные ошибки 500 - 599

Эти коды подробно описаны в 10-й секции RFC 2616. Обновленная спецификация представлена в RFC 7231.

Если вы столкнулись с не указанным в списке кодом состояния, он, скорее всего, является нестандартизированным или пользовательским.

В таблице ниже перечислены коды состояния HTTP и их значение:

Код ответа Название Описание Версия HTTP
Информационные
100 Continue "Продолжить". Этот промежуточный ответ указывает, что запрос успешно принят и клиент может продолжать выполнение запроса или игнорировать ответ, если запрос завершен. Только HTTP/1.1
101 Switching Protocol "Переключение протокола". Этот код посылается в ответ при наличии в запросе клиента заголовка Upgrade, указывая, что сервер переключился на протокол, указанный в этом заголовке. Только HTTP/1.1
102 Processing "В обработке". Означает, что сервер получил запрос, но его обработка еще не завершена. Только HTTP/1.1
103 Early Hints "Ранние подсказки". Этот ответ сообщает о ресурсах, которые могут быть загружены заранее, пока сервер готовит основной ответ. Только HTTP/1.1
Успешные
200 OK "Успешно". Запрос удачно обработан. В зависимости от метода HTTP, который запрашивался:
  • GET: Ресурс найден и передан в теле ответа.
  • HEAD: Заголовки информации переданы в ответе.
  • POST: Ресурс, описывающий результат действия сервера на запрос, передается в ответе.
  • TRACE: Тело ответа содержит тело запроса, полученного сервером.
HTTP/0.9 и выше
201 Created "Создано". Запрос успешно выполнен и был создан новый ресурс, обычно в ответ на PUT. HTTP/0.9 и выше
202 Accepted "Принято". Запрос принят, но пока не обработан. Отсутствует стандартный способ послать асинхронный ответ позже, чтобы показать итоги обработки запроса. Этот код используется, когда запрос обрабатывается другим процессом или сервером или для пакетной обработки. HTTP/0.9 и выше
203 Non-Authoritative Information "Информация не авторитетна". Ответ означает, что информация не поступила от исходного сервера, а из другого источника. Предпочтительнее использовать ответ 200 OK в остальных случаях. HTTP/0.9 и выше
204 No Content "Нет содержимого". Нет содержимого для возврата, но заголовки ответа полезны для обновления кешированных заголовков ресурса. HTTP/0.9 и выше
205 Reset Content "Сбросить содержимое". Сообщает, что необходимо сбросить отображение документа, приславшего запрос. Только HTTP/1.1
206 Partial Content "Частичное содержимое". Присылается при запросе с заголовком диапазона для осуществления загрузки в несколько потоков. Только HTTP/1.1
Сообщения о перенаправлениях
300 Multiple Choice "Множественный выбор". Присылается, когда запрос имеет несколько возможных ответов, и User-agent или пользователь должен выбрать один. Стандарта выбора среди них не существует. HTTP/1.0 и выше
301 Moved Permanently "Перемещён навсегда". Указывает, что URI ресурса изменился и, возможно, новый URI будет указан в ответе. HTTP/0.9 и выше
302 Found "Найдено". Указывает на временное изменение ресурса. Этот URI может быть использован в будущем клиентом для запросов. HTTP/0.9 и выше
303 See Other "Смотреть другие ресурсы". Клиента перенаправляют для получения ресурса на другой URI с помощью GET-запроса. HTTP/0.9 и 1.1
304 Not Modified "Не модифицировано". Означает, что ресурс не был изменен и клиент может продолжать использовать кешированную версию. HTTP/0.9 и выше
305 Use Proxy "Используйте прокси". Требует, чтобы ресурс имелся через прокси. В основном игнорируется из-за вопросов безопасности. Только HTTP/1.1
306 Switch Proxy "Больше не используется". Изначально передавалась информация о необходимости использования другого прокси в последующих запросах. Только HTTP/1.1
307 Temporary Redirect "Временное перенаправление". Дает клиенту ресурс по другому URL-адресу с первоначальным методом, без смены метода HTTP в запросах. Только HTTP/1.1
308 Permanent Redirect "Постоянное перенаправление". Указывает, что ресурс находится по другому постоянному URI, метод HTTP в запросах не изменяется. Семантика соответствует 301.

Примечание: Экспериментальный код, текущая спецификация в черновике.

draft-reschke-http-status-308
Клиентские ошибки
400 Bad Request "Плохой запрос". Синтаксис запроса неверен, и сервер его не понимает. HTTP/0.9 и выше
401 Unauthorized "Неавторизирован". Требуется аутентификация для получения запрашиваемого ответа. Аутентификация допускается, в отличие от 403. HTTP/0.9 и выше
402 Payment Required "Требуется оплата". Зарезервирован для будущих целей. Первоначально планировалось для цифровых платежных систем, но сейчас не используется. HTTP/0.9 и 1.1
403 Forbidden "Запрещено". Доступ к содержимому клиента ограничен, и сервер отвечает отказом в разрешении. HTTP/0.9 и выше
404 Not Found "Не найден". Сервер не может найти запрашиваемый ресурс. Это один из наиболее распространенных кодов ошибок в интернете. HTTP/0.9 и выше
405 Method Not Allowed "Метод не поддерживается". Метод известен серверу, но не разрешён. GET и HEAD методы должны быть всегда разрешены. Только HTTP/1.1
406 Not Acceptable Отправляется, когда сервер не находит контента, который удовлетворяет критериям, указанным в user agent после server-driven content negotiation. Только HTTP/1.1
407 Proxy Authentication Required Аналогично 401, но требуется аутентификация для прокси-сервера. Только HTTP/1.1
408 Request Timeout Сообщает о намерении сервера разорвать неиспользуемое соединение. Используется все чаще, особенно ввиду механизмов предварительного соединения в браузерах для ускорения загрузки. Только HTTP/1.1
409 Conflict Указывает на конфликт запроса с текущим состоянием ресурса или сервера. Только HTTP/1.1
410 Gone Означает, что запрашиваемый ресурс навсегда удален с сервера. Только HTTP/1.1
411 Length Required Запрос отклонен из-за отсутствия заголовка Content-Length. Только HTTP/1.1
412 Precondition Failed Клиентские заголовки содержат условия, которые сервер не может выполнить. Только HTTP/1.1
413 Request Entity Too Large Размер запроса превосходит объявленные сервером ограничения, сервер может закрыть соединение, вернув заголовок Retry-After. Только HTTP/1.1
414 Request-URI Too Long URI слишком длинный для обработки сервером. Только HTTP/1.1
415 Unsupported Media Type Медиа-формат данных не поддерживается сервером, поэтому запрос отвергается. Только HTTP/1.1
416 Requested Range Not Satisfiable Диапазон в заголовке запроса недоступен или превышает пределы URI. Только HTTP/1.1
417 Expectation Failed Ожидания, указанные в заголовке Expect запроса, сервер выполнить не может. Только HTTP/1.1
Серверные ошибки
500 Internal Server Error "Внутренняя ошибка сервера". Возникает при ситуациях, для которых сервер не может предложить решение. HTTP/0.9 и выше
501 Not Implemented "Не реализовано". Метод запроса не поддерживается сервером и не может быть выполнен. Серверы должны поддерживать GET и HEAD. HTTP/0.9 и выше
502 Bad Gateway "Плохой шлюз". Получена неверная реакция на шлюзе, обрабатывающем запрос. HTTP/0.9 и выше
503 Service Unavailable "Сервис недоступен". Сервер не может обработать запрос по причине временных проблем, таких как отключение или перегрузка, желательно сопроводить удобной страницей с причиной проблемы. HTTP/0.9 и выше
504 Gateway Timeout Ошибка сообщает о невозможности получения ответа в течение времени, установленного шлюзом. Только HTTP/1.1
505 HTTP Version Not Supported "HTTP-версия не поддерживается". Версия HTTP, используемая в запросе, сервером не поддерживается. Только HTTP/1.1

Вопросы для самопроверки:

  1. Что такое архитектура REST и какие ее основные преимущества?
  2. Какие критерии должны выполняться, чтобы система считалась RESTful?
  3. Какой HTTP метод используется для создания ресурсов, а какой для их обновления?
  4. В чем заключается понятие идемпотентности в контексте REST?
  5. Каковы отличия между кодами состояния HTTP из категорий информационных, успешных, перенаправлений, клиентских ошибок и серверных ошибок?