HTTP
HTTP для API
Поиск…
замечания
HTTP API используют широкий спектр HTTP-глаголов и обычно возвращают ответы JSON или XML.
Создать ресурс
Не все согласны с тем, что наиболее семантически правильный метод для создания ресурсов. Таким образом, ваш API может принимать запросы POST
или PUT
или либо.
Сервер должен ответить на 201 Created
если ресурс был успешно создан. Выберите наиболее подходящий код ошибки, если это не так.
Например, если вы предоставляете API для создания записей сотрудников, запрос / ответ может выглядеть так:
POST /employees HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Charlie Smith",
"age": 38,
"job_title": "Software Developer",
"salary": 54895.00
}
HTTP/1.1 201 Created
Location: /employees/1/charlie-smith
Content-Type: application/json
{
"employee": {
"name": "Charlie Smith",
"age": 38,
"job_title": "Software Developer",
"salary": 54895.00
"links": [
{
"uri": "/employees/1/charlie-smith",
"rel": "self",
"method": "GET"
},
{
"uri": "/employees/1/charlie-smith",
"rel": "delete",
"method": "DELETE"
},
{
"uri": "/employees/1/charlie-smith",
"rel": "edit",
"method": "PATCH"
}
]
},
"links": [
{
"uri": "/employees",
"rel": "create",
"method": "POST"
}
]
}
Включение links
полей JSON в ответе позволяет клиенту получить доступ к ресурсу, связанному с новым ресурсом и к приложению в целом, без предварительного уведомления об их URI или методах.
Редактировать ресурс
Редактирование или обновление ресурса является общей целью для API. Редактирование может быть достигнуто путем отправки запросов POST
, PUT
или PATCH
на соответствующий ресурс. Хотя POST
разрешено добавлять данные в существующее представление ресурса, рекомендуется использовать PUT
или PATCH
поскольку они передают более явный семантик.
Ваш сервер должен ответить 200 OK
если обновление было выполнено, или 202 Accepted
если он еще не применен. Выберите наиболее подходящий код ошибки, если он не может быть завершен.
Полные обновления
PUT
имеет семантику замены текущего представления на полезную нагрузку, включенную в запрос. Если полезная нагрузка не имеет тот же тип представления, что и текущее представление ресурса для обновления, сервер может решить, какой подход принять. RFC7231 определяет, что сервер может либо
- Переконфигурируйте целевой ресурс для отражения нового типа носителя
- Преобразуйте представление PUT в формат, совместимый с форматом resouce, прежде чем сохранять его как новое состояние ресурса
- Отклоните запрос с ответом
415 Unsupported Media Type
указывающим, что целевой ресурс ограничен определенным (установленным) типом медиа.
Базовый ресурс, содержащий представление JSON HAL, например ...
{
"name": "Charlie Smith",
"age": 39,
"job_title": "Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
}
}
... может получить запрос на обновление, подобный этому
PUT /users/1234 HTTP/1.1
Host: http://www.acmee.com
Content-Type: "application/json; charset=utf-8"
Content-Length: 85
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer"
}
Теперь сервер может заменить состояние ресурса данным объектом запроса, а также изменить тип контента из application/hal+json
в application/json
или преобразовать полезную нагрузку JSON в представление JSON HAL, а затем заменить содержимое ресурса с преобразованным или отклонить запрос на обновление из-за неприменимого типа носителя с ответом 415 Unsupported Media Type
.
Существует разница между заменой содержимого напрямую или первым преобразованием представления в модель определенного представления, а затем заменой существующего содержимого на преобразованный. Последующий GET
вернет следующий ответ на прямую замену:
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer"
}
в то время как преобразование, а затем заменит подход, вернет следующее представление:
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: e0023aa4e
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
}
}
Побочные эффекты
Обратите внимание, что PUT
разрешено иметь побочные эффекты, хотя он определен как идемпотентная операция! Это описано в RFC7231 как
Запрос PUT, применяемый к целевому ресурсу, может иметь побочные эффекты для других ресурсов . Например, статья может иметь URI для идентификации «текущей версии» (ресурса), которая отделена от URI, идентифицирующих каждую конкретную версию (разные ресурсы, которые в одной точке разделяют то же состояние, что и ресурс текущей версии). Таким образом, успешный запрос PUT на URI «текущей версии» может создать ресурс новой версии в дополнение к изменению состояния целевого ресурса и может также привести к добавлению ссылок между связанными ресурсами.
Создание дополнительных записей в журнале не считается побочным эффектом, так как это, конечно, не состояние ресурса в целом.
Частичные обновления
RFC7231 упоминает об частичных обновлениях:
Обновления частичного контента возможны путем таргетинга отдельно идентифицированного ресурса с состоянием, которое перекрывает часть более крупного ресурса, или с помощью другого метода, который был определен специально для частичных обновлений (например, метода PATCH, определенного в RFC5789 ).
Поэтому частичные обновления могут быть выполнены в двух вариантах:
- Попросите ресурс внедрить несколько меньших под-ресурсов и обновить только соответствующий подресурс, а не полный ресурс через
PUT
- Используя
PATCH
и проинструктируйте сервер, что обновлять
Частичное обновление с перекрывающимся состоянием
Если представление пользователя необходимо частично обновить из-за перемещения пользователя в другое место, вместо того, чтобы напрямую обновлять пользователя, связанный ресурс должен быть обновлен напрямую, что отражает частичное обновление представления пользователя.
Перед перемещением пользователь имел следующее представление
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept: application/hal+json; charset=utf-8
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
},
"_embedded": {
"ea:address": {
"street": "Terrace Drive, Central Park",
"zip": "NY 10024"
"city": "New York",
"country": "United States of America",
"_links": {
"self": { "href": "/address/abc" },
"google_maps": { "href": "http://maps.google.com/?ll=40.7739166,-73.970176" }
}
}
}
}
По мере того, как пользователь переезжает в новое место, она обновляет свою информацию о местоположении следующим образом:
PUT /address/abc HTTP/1.1
Host: http://www.acmee.com
Content-Type: "application/json; charset=utf-8"
Content-Length: 109
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
{
"street": "Standford Ave",
"zip": "CA 94306",
"city": "Pablo Alto",
"country": "United States of America"
}
С семантикой transform-before-replace для несоответствующего медиа-типа между существующим ресурсом адреса и тем, который указан в запросе, как описано выше, ресурс адреса теперь обновляется, что имеет последствия для последующего запроса GET
на пользовательском ресурсе возвращается новый адрес для пользователя.
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept: application/hal+json; charset=utf-8
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
},
"_embedded": {
"ea:address": {
"street": "Standford Ave",
"zip": "CA 94306",
"city": "Pablo Alto",
"country": "United States of America"
"_links": {
"self": { "href": "/address/abc" },
"google_maps": { "href": "http://maps.google.com/?ll=37.4241311,-122.1524475" }
}
}
}
}
Исправление частичных данных
PATCH
определен в RFC5789 и не является непосредственно частью спецификации HTTP как таковой. Общим недоверием является то, что отправка только полей, которые должны быть частично обновлены, достаточно в рамках запроса PATCH
. Поэтому в спецификации указывается
Метод PATCH запрашивает, чтобы набор изменений, описанных в объекте запроса, был применен к ресурсу, идентифицированному Request-URI. Набор изменений представлен в формате, называемом «патч-документом», идентифицированным типом носителя.
Это означает, что клиент должен вычислить необходимые шаги, необходимые для преобразования ресурса из состояния A в состояние B и отправки этих инструкций на сервер.
Популярным медиа-типом на основе JSON для исправления является JSON Patch .
Если возраст и название работы нашего образца пользователя меняются, а дополнительное поле, представляющее доход пользователя, должно быть добавлено, частичное обновление с использованием PATCH
с использованием JSON Patch может выглядеть следующим образом:
PATCH /users/1234 HTTP/1.1
Host: http://www.acmee.com
Content-Type: application/json-patch+json; charset=utf-8
Content-Length: 188
Accept: application/json
If-Match: "e0023aa4e"
[
{ "op": "replace", "path": "/age", "value": 40 },
{ "op": "replace", "path": "/job_title", "value": "Senior Software Developer" },
{ "op": "add", "path": "/salery", "value": 63985.00 }
]
PATCH
может обновлять сразу несколько ресурсов и требует, чтобы эти изменения применялись атомарно, что означает, что все изменения должны быть применены или вообще отсутствуют, что ставит транзакционную нагрузку на разработчика API.
Успешное обновление может вернуть что-то вроде этого
HTTP/1.1 200 OK
Location: /users/1234
Content-Type: application/json
ETag: "df00eb258"
{
"name": "Charlie Smith",
"age": 40,
"job_title": "Senior Software Developer",
"salary": 63985.00
}
хотя не ограничивается только 200 OK
кодами ответа 200 OK
.
Чтобы предотвратить промежуточные обновления (изменения, сделанные между предыдущей выборкой состояния представления и обновлением), следует использовать заголовок ETag
, If-Match
или If-Unmodified-Since
.
Обработка ошибок
Спецификация на PATCH
рекомендует следующую обработку ошибок:
Тип | Код ошибки |
---|---|
Недопустимый файл патча | 400 Bad Request |
Неподдерживаемый патч-документ | 415 Unsupported Media Type |
Непроцессный запрос, т. Е. Если resoure станет недействительным, применив патч | 422 Unprocessable Entity |
Ресурс не найден | 404 Not Found |
Конфликтующее состояние, то есть переименование (перемещение) поля, которое не существует | 409 Conflict |
Конфликтная модификация, то есть, если клиент использует заголовок If-Match или If-Unmodified-Since проверка которого не удалась. Если предварительное условие не было доступно, последний код ошибки должен быть возвращен | 412 Precondition Failed или 409 Conflict |
Параллельная модификация, то есть, если запрос должен быть применен до принятия дальнейших запросов PATCH | 409 Conflict |
Удалить ресурс
Другим распространенным применением HTTP API является удаление существующего ресурса. Обычно это делается с помощью запросов DELETE
.
Если удаление было успешным, сервер должен вернуть 200 OK
; соответствующий код ошибки, если это не так.
Если наш сотрудник Чарли Смит покинул компанию, и теперь мы хотим удалить его записи, это может выглядеть так:
DELETE /employees/1/charlie-smith HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
'links': [
{
'uri': '/employees',
'rel': 'create',
'method': 'POST'
}
]
}
Список ресурсов
Последнее общее использование HTTP API - это получение списка существующих ресурсов на сервере. Списки, подобные этому, должны быть получены с использованием запросов GET
, поскольку они только извлекают данные.
Сервер должен вернуть 200 OK
если он может предоставить список, или соответствующий код ошибки, если нет.
Таким образом, список наших сотрудников может выглядеть так:
GET /employees HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
'employees': [
{
'name': 'Charlie Smith',
'age': 39,
'job_title': 'Software Developer',
'salary': 63985.00
'links': [
{
'uri': '/employees/1/charlie-smith',
'rel': 'self',
'method': 'GET'
},
{
'uri': '/employees/1/charlie-smith',
'rel': 'delete',
'method': 'DELETE'
},
{
'uri': '/employees/1/charlie-smith',
'rel': 'edit',
'method': 'PATCH'
}
]
},
{
'name': 'Donna Prima',
'age': 30,
'job_title': 'QA Tester',
'salary': 77095.00
'links': [
{
'uri': '/employees/2/donna-prima',
'rel': 'self',
'method': 'GET'
},
{
'uri': '/employees/2/donna-prima',
'rel': 'delete',
'method': 'DELETE'
},
{
'uri': '/employees/2/donna-prima',
'rel': 'edit',
'method': 'PATCH'
}
]
}
],
'links': [
{
'uri': '/employees/new',
'rel': 'create',
'method': 'PUT'
}
]
}