Как поддерживать частичные обновления (PATCH) в REST
Я хочу реализовать частичные обновления для своего ресурса, так как у меня большой ресурс и я хочу обновить частичную информацию из него. Я прошел по следующим ссылкам, но не
возможность выяснить, использовать ли методы HTTP POST или PATCH.
Как отправить RESTful частичные обновления?
http://jacobian.org/writing/rest-worst-practices/
https://github.com/archiloque/rest-client/issues/79
http://tools.ietf.org/html/draft-dusseault-http-patch-16
http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-06.html
http://jasonsirota.com/rest-partial-updates-use-post-put-or-patch
http://bitworking.org/news/296/How-To-Do-RESTful-Partial-Updates
https://github.com/dharmafly/jsonpatch.js
Пожалуйста, предложите любое правильное решение для этого.
3 ответа
Согласно RFC5789 ( http://tools.ietf.org/html/rfc5789), это именно то, для чего предназначен PATCH:
Некоторым приложениям, расширяющим протокол передачи гипертекста (HTTP), требуется функция для частичной модификации ресурса. Существующий метод HTTP PUT позволяет только полную замену документа. Это предложение добавляет новый метод HTTP, PATCH, для изменения существующего ресурса HTTP.
Различие между PATCH и PUT описывается так:
Разница между запросами PUT и PATCH отражается в способе, которым сервер обрабатывает вложенный объект для изменения ресурса, идентифицируемого Request-URI. В запросе PUT вложенный объект считается модифицированной версией ресурса, хранящегося на исходном сервере, и клиент запрашивает замену сохраненной версии. Однако с помощью PATCH вложенный объект содержит набор инструкций, описывающих, как ресурс, находящийся в данный момент на исходном сервере, должен быть модифицирован для создания новой версии.
Ограничения POST также описаны:
Метод PUT уже определен для перезаписи ресурса новым телом и не может использоваться повторно для частичных изменений. В противном случае прокси и кеши, и даже клиенты и серверы, могут запутаться в результате выполнения операции. POST уже используется, но без широкой совместимости (во-первых, нет стандартного способа обнаружить поддержку формата патча) [...]
Я бы посоветовал вам прочитать RFC и составить собственное мнение, но мне это кажется довольно четким - запросы PATCH должны обрабатываться как частичные обновления. (NB они НЕ идемпотентны, в отличие от PUT.)
РЕДАКТИРОВАТЬ: как указал Евгений в комментариях, хотя запросы PATCH "neither safe nor idempotent as defined by [RFC2616]"
, их можно сделать так:
Запрос PATCH может быть выдан таким образом, чтобы быть идемпотентным, что также помогает предотвратить плохие исходы от коллизий между двумя запросами PATCH на одном и том же ресурсе в течение аналогичного периода времени. Коллизии из нескольких запросов PATCH могут быть более опасными, чем коллизии PUT, потому что некоторые форматы патчей должны работать с известной базовой точки, иначе они повредят ресурс. Клиенты, использующие этот тип приложения исправлений, ДОЛЖНЫ использовать условный запрос, так что запрос не будет выполнен, если ресурс был обновлен с момента последнего доступа клиента к ресурсу. Например, клиент может использовать сильный ETag [RFC2616] в заголовке If-Match в запросе PATCH.
Вы должны использовать метод PATCH, как описано в RFC-7386 "json merge PATCH".
Например, если вы хотите изменить значение "a" и удалить "f" в ресурсе, например:
{
"a": "b",
"c": {
"d": "e",
"f": "g"
}
}
Вы можете достичь этого, отправив:
PATCH /target HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json
{
"a":"z",
"c": {
"f": null
}
}
PATCH должен использоваться с форматом патча, только для патчей на уровне документа (иначе, как в реальном представлении). Его использование для других целей является сомнительным и спорным, и не ясно, что этот метод был разработан для использования не-СМИ типа.
В целом, POST будет правильным подходом, но вы можете вместо этого разделить свой ресурс на несколько ресурсов и изменить их.
[Отредактировано для ясности, так как некоторые не читают комментарии]