Веб-сервисы RESTful

Продолжение статьи. Читать с начала.

Адресация ресурсов

REST требует, чтобы каждый ресурс имел по меньшей мере один URI. Сервис RESTful использует иерархию каталогов подобную читабельным URI для адресации ресурсов. Работой URI является идентификация ресурса или коллекции ресурсов. Фактически операция определяется HTTP глаголом. URI не должен говорить что-нибудь об операции или действии. Это дает нам возможность вызывать один и тот же URI с различными HTTP глаголами, чтобы производить различные операции.

Предположим у нас есть база данных лиц, и мы хотим выставить их во внешний мир с помощью сервиса. Ресурс person может быть адресован так:

http://MyService/Persons/1

Этот URL имеет следующий формат: Протокол://ИмяСервиса/Тип ресурса/ИДРесурса

Некоторые важные рекомендации для хорошо структурированных URI:

Параметры запросов в URI

Предыдущий URI конструировался с помощью параметра запроса:

http://MyService/Persons?id=1

Подход с параметрами запроса работает прекрасно, и REST не препятствует вам использовать параметры. Однако этот подход имеет несколько недостатков.

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

http://MyService/Persons/1?format=xml&encoding=UTF8
или
http://MyService/Persons/1?format=json&encoding=UTF8

Включение здесь параметров format и encoding в основной URI в иерархии родитель-ребенок не будет логически корректным, поскольку они не имеют такой связи:

http://MyService/Persons/1/json/UTF8

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

Однородный интерфейс

RESTful-системы должны иметь однородный интерфейс. Для достижения этой цели HTTP 1.1 предоставляет набор методов, называемых глаголами. Наиболее важными среди них являются:

МетодОперация, выполняемая на сервереКачество
GETЧитает ресурсБезопасный
PUTВставляет новый ресурс или обновляет, если ресурс уже существует.Идемпотентный
POSTВставляет новый ресурс. Также может использоваться для обновления существующего ресурса.N/A
DELETEУдаляет ресурс.Идемпотентный
OPTIONSСписок допустимых операций на ресурсе.Безопасный
HEADВозвращает только заголовки ответа, но не тело.Безопасный

Безопасной называется операция, которая не оказывает никакого эффекта на оригинальное значение ресурса. Например, математическое деление на 1 является безопасной операцией, поскольку сколько бы вы не делили на 1, оригинальное значение не изменится. Идемпотентная операция – это операция, которая дает тот же результат, сколько её ни применяй. Например, математическое умножение на 0 является идемпотентной операцией, поскольку всегда дает один и тот же результат. Аналогично безопасный метод HTTP не вносит никаких изменений в ресурс на сервере. Идемпотентный метод HTTP имеет один и тот же эффект, сколько бы раз ни применялся. Классифицируя методы как безопасные и идемпотентные, легко предсказать результаты в ненадежном окружении веба, где клиент может повторить тот же запрос.

GET – наиболее популярный метод в Веб. Он используется для выборки ресурса.

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

Метод OPTIONS используется для получения списка допустимых операций на ресурсе. Например, рассмотрим запрос:

1	OPTIONS http://MyService/Persons/1 HTTP/1.1
2	HOST: MyService	

Сервис после авторизации и аутентификации запроса может вернуть что-то типа:

1	200 OK
2	Allow: HEAD, GET, PUT	

Вторая строка содержит список операций, которые разрешены клиенту.

Вы должны использовать эти методы только по назначению. Например, никогда не используйте GET для создания или удаления ресурса на сервере. В противном случае это смутит ваших клиентов, и они могут прекратить выполнять непреднамеренные операции. Для иллюстрации рассмотрим такой запрос:

1	GET http://MyService/DeletePersons/1 HTTP/1.1
2	HOST: MyService

Согласно спецификации HTTP 1.1 запрос GET предназначен для выборки ресурсов с сервера. Однако легко сделать, чтобы ваш сервис фактически удалил Person. Этот запрос может работать прекрасно, но это не будет структурой RESTful. Вместо этого используйте метод DELETE для удаления ресурса:

1	DELETE http://MyService/Persons/1 HTTP/1.1
2	HOST: MyService

REST рекомендует однородный интерфейс, и HTTP обеспечивает вам этот интерфейс. Однако разработчики сервисов и клиенты должны следовать этой однородности.

Разница между PUT и POST

Ключевое различие между PUT и POST заключается в том, что PUT является идемпотентным, в то время как POST - нет. Не важно сколько раз вы будете отправлять запрос PUT , ответ будет одним и тем же. POST не является идемпотентным методом. Выполняя POST несколько раз, вы получите несколько ресурсов, созданных на сервере.

Другое отличие состоит в том, что при PUT вы всегда должны указывать полный URI ресурса. Это подразумевает, что клиент должен конструировать URI ресурса, даже если он еще не существует на сервере. Это возможно, когда делом клиента является выбрать уникальное имя или ID для ресурса, когда, например, при создании пользователя на сервере требуется, чтобы клиент выбрал ID пользователя. Если клиент не может угадать полный URI ресурса, тогда у вас нет другой возможности, кроме как использовать POST.

ЗапросОперация
PUT http://MyService/Persons/Не должно работать. PUT требует полного URI.
PUT http://MyService/Persons/1Вставить новое лицо с PersonID=1, если такого еще не существует, в противном случае обновить существующий ресурс.
POST http://MyService/Persons/Вставляет новое лицо всякий раз, когда выполняется запрос, и генерирует новый PersonID.
POST http://MyService/Persons/1Обновляет существующее лицо, с PersonID=1.

Из таблицы ясно, что PUT-запрос не будет модифицировать или создавать более одного ресурса вне зависимости от того, сколько раз он был выполнен (если URI тот же самый). Нет разницы между PUT и POST, если ресурс уже существует, оба обновляют существующий ресурс. Третий запрос (POST http://MyService/Persons/) будет создавать ресурс при каждом выполнении. Множество разработчиков думают, что REST не допускает, чтобы POST использовался для операции обновления; однако REST не предполагает таких ограничений.

страницы 1 2 3