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

HTTP глаголы составляют основную часть "единого интерфейса", ограничивающего и предоставляющего возможность осуществлять действия над существительным-ресурсом. Основными или наиболее часто используемыми HTTP глаголами (или методами, как их иногда называют) являются POST, GET, PUT, и DELETE. Они соответствуют операциям создания, чтения, обновления и удаления (или в совокупности - CRUD). Есть еще и другие глаголы, но они используются реже. Из реже используемых методов выделяются OPTIONS и HEAD

Ниже приведена сводная таблица рекомендаций по возвращению значений при использовании основных HTTP глаголов в сочетании с ресурсами URI:

HTTP Глагол Ресурс (например /customers) Экземпляр (например /customers/{id})
GET 200 (OK), перечень customers. Используется постраничная навигация, сортировка и фильтрация для больших списков. 200 (OK), конкретный customer. 404 (Not Found), в случае отсутствия экземпляра с указанным ID или если он не корректен (а также, если клиенту не позволительно знать о наличии данного экземпляра).
PUT 404 (Not Found), если была попытка обновить/заменить экземпляр во всей коллекции. 200 (OK) или 204 (No Content). 404 (Not Found), в случае отсутствия экземпляра с указанным ID или если он не корректен (а также, если клиенту не позволительно знать о наличии данного экземпляра).
POST 201 (Created), заголовок 'Location' ссылается на /customers/{id}, где ID - идентификатор нового экземпляра. 404 (Not Found).
DELETE 404 (Not Found), если вы хотите удалить вс коллекцию, что крайне не желательно. 200 (OK) или 204 (No Content). 404 (Not Found), в случае отсутствия экземпляра с указанным ID или если он не корректен (а также, если клиенту не позволительно знать о наличии данного экземпляра).

Ниже приводится более подробное обсуждение основных методов HTTP. Используйте навигацию по вкладкам для получения дополнительных сведений о интересуемом HTTP методе.

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

В соответствии спецификации HTTP, GET (также как и HEAD) запросы используются только для чтения данных, не изменя их. Таким образом, при соблюдении данного соглашения, они считаются безопасными. То есть они могут использоваться без риска изменения данных, вне зависимости от того, один раз данные были получены, или же 10, или ни разу вовсе. GET (а также HEAD) запросы являются идемпотентными (тождественными), что подразумевает получение идеинтичных данных при использовании одних и теж же запросов (как при единичном обращении, так и при многократном).

Не стоит использовать GET для небезопасных операций над данными, при данном запросе они не должны быть модифицированы.

Примеры:

  • GET http://www.example.com/customers/12345
  • GET http://www.example.com/customers/12345/orders
  • GET http://www.example.com/buckets/sample

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

Кроме того, PUT может быть использован для создания ресурса, в случае, когда идентификатор ресурса выбирает клиент а не сервер. Или, если перефразировать - при отправке PUT запроса по адресу, содержащему не существующий идентификатор ресурса. Опять же, стоит помнить, что тело запроса должно быть модификацией оригинального ресурса. Многие считают это запутанным и не понятным. Соответственно, данную возможность метода PUT стоит использовать с осторожностью. Да и при крайней необходимости.

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

При успешном обновлении посредством выполнения PUT запроса возвращается код 200 (или 204 если не был передан какой либо контент в теле ответа). Если PUT используется для создания экземпляра - обычно возвращают HTTP код 201 при успешном создании. Возвращать данные в ответ на запрос не обязательно. Также не обязательно возвращать ссылку на экземпляр ресурса посредством заголовка `Location` по причине того, что клиент и так обладает идентификатором экземпляра ресурса.

PUT не безопасная операция, так как в следствии ее выполнения происходит модификация (или создание) экземпляров ресурса на стороне сервера, но этот метод идемпотентен. Другими словами, создание или обновление ресурса посредством отправки PUT запроса - ресурс не исчезнет, будет располагаться там же, где и был при первом обращении, а также, многократное выполнение одного и того же PUT запроса не изменит общего состояния системы (за исключением первого раза, но это обычно опускают из рассмотрения)

Если PUT запрос используется для увеличесния счетчика просмотра конкретного ресурса - данный запрос уже не считается идемпотентным. Иногда такое происходит и считается достаточным задокументировать тот факт, что вызов не идемпотентен. Однако, строго рекомендуется выдерживать идемпотентность PUT запроса.

Примеры:

  • PUT http://www.example.com/customers/12345
  • PUT http://www.example.com/customers/12345/orders/98765
  • PUT http://www.example.com/buckets/secret_stuff

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

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

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

Примеры:

  • POST http://www.example.com/customers
  • POST http://www.example.com/customers/12345/orders

DELETE запрос крайне прост для понимания. Он используется для удаления ресурса, идентифицированного конкретным URI (ID).

При успешном удалении возвращается 200 (OK) код HTTP, совместно с телом ответа, содаржащим данные удаленного ресурса (отрицательно сказывается на экономии трафика) или завернутые ответы (Смотрите "Возвращаемые данные"). Также возможно использование HTTP кода 204 (NO CONTENT) без тела ответа.

Согласно спецификации HTTP, DELETE запрос идемпотентен. Если вы выполняете DELETE запрос к ресурсу, он удаляется. Повторный DELETE запрос к ресурсу закончится также: ресурс удален. Если DELETE запрос используется для декремента счетчика, DELETE запрос не является идемпотентным. Используйте POST для не идемпотентых операций.

Тем не менее, существует предостережение об идемпотентности DELETE. Повторный DELETE запрос к ресурсу часто сопровождается 404 (NOT FOUND) кодом HTTP по причине того, что ресурс уже удален (например из базы данных) и более не доступен. Это делает DELETE операцию не идемпотентной, но это общепринятый компромисс на тот случай, если ресурс был удален из базы данных, а не помечен, как удаленный.

Примеры:

  • DELETE http://www.example.com/customers/12345
  • DELETE http://www.example.com/customers/12345/orders
  • DELETE http://www.example.com/bucket/sample

Fork me on GitHub