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, она должна удовлетворять следующим критериям:
- Client-Server: Разделение системы на клиенты и серверы. Это обеспечивает независимость клиента от хранения данных и улучшает мобильность кода. Серверы не взаимодействуют с интерфейсом пользователя, что упрощает их конструкцию и масштабируемость.
- Stateless: Сервер не хранит информацию по клиентам. В запросе должна содержаться вся необходимая информация для его обработки и идентификации клиента.
- Cache: Кэширование ответов обязательно, чтобы предотвратить использование клиентами некорректных данных в будущем.
-
Uniform Interface: Унифицированный интерфейс, обеспечивающий надежную связь между клиентами и
серверами, подчеркивается четырьмя ключевыми принципами:
Эти принципы включают:
- Ресурсная идентификация: в REST ресурсом считается все, что можно назвать. Каждый ресурс должен иметь стабильный идентификатор, иначе идентификатор, не зависящий от состояния ресурса, выражается URI.
- Манипуляция ресурсами через представления: Представление позволяет работать с ресурсом, показывая его текущее или желаемое состояние, скажем, в форме XML или HTML.
- Самодокументируемые сообщения: Все нужные данные содержатся в запросе и ответе, исключая дополнительные сообщения или кэши, важное условие для масштабируемой системы.
- HATEOAS: Использует гипермедиа для отображения состояния приложения, ссылки в ответе помогают управлять URI и сделают его самоописанием.
- Layered System: Позволяет деление системы на иерархические слои, где каждый элемент взаимодействует исключительно со следующим близким уровнем.
- 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 отражает, был ли запрос обработан успешно. Коды делятся на пять основных категорий:
- Информационные 100 - 199
- Успешные 200 - 299
- Перенаправления 300 - 399
- Клиентские ошибки 400 - 499
- Серверные ошибки 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, который запрашивался:
|
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 |