Является ли частичное представление документа допустимым набором изменений в соответствии с HTTP PATCH RFC?

Вот что говорится в RFC 5789:

Метод PATCH запрашивает, чтобы набор изменений, описанных в объекте запроса, был применен к ресурсу, указанному Request-URI. Набор изменений представлен в формате, называемом документом исправления, идентифицируемым по типу носителя. Если Request-URI не указывает на существующий ресурс, сервер МОЖЕТ создать новый ресурс в зависимости от типа документа исправления (может ли он логически изменить пустой ресурс) и разрешений и т. д.

Разница между запросами PUT и PATCH отражается в том, как сервер обрабатывает вложенный объект для изменения ресурса, идентифицированного Request-URI. В запросе PUT вложенный объект считается измененной версией ресурса, хранящегося на исходном сервере, и клиент запрашивает замену сохраненной версии. Однако с PATCH вложенный объект содержит набор инструкций, описывающих, как ресурс, находящийся в настоящее время на исходном сервере, должен быть изменен для создания новой версии.

Допустим, у меня есть { "login": "x", "enabled": true }, и я хочу его отключить.

Согласно сообщению Пожалуйста. Не исправляйте как идиот. правильный запрос PATCH будет

[{ "op": "replace", "path": "/enabled", "value": false }]

Однако возьмем этот запрос:

{ "enabled": false }

Он также «содержит набор инструкций, описывающих, как следует модифицировать ресурс, находящийся в настоящее время на исходном сервере», с той лишь разницей, что вместо объекта JSON используется свойство JSON.

Это кажется менее мощным, но при необходимости изменения массива могут иметь другой специальный синтаксис (например, {"a":{"add":[], "remove":[]}}), и логика сервера в любом случае может не справиться с чем-то более мощным.

Является ли это неправильным запросом PATCH в соответствии с RFC? И если да, то почему?
И, с другой стороны, будет ли { "op": "disable" } правильным запросом PATCH?


person Andrey Shchekin    schedule 03.09.2014    source источник


Ответы (1)


единственное отличие состоит в том, что вместо объекта JSON используется свойство JSON.

Это на самом деле немного глубже, чем это. Ссылка на RFC 6902 важна. Первый запрос имеет Content-Type из application/json-patch+json, а второй — application/json.

Важно то, что вы используете тип носителя diff, который полезен для этой цели. Вам не обязательно использовать JSON-PATCH (я большой поклонник json-merge-patch), но вы не можете просто использовать все, что хотите. То, о чем вы спрашиваете во второй части, это, по сути, «могу ли я создать свой собственный тип носителя», и ответ «да», просто задокументируйте это и зарегистрируйте в IANA.

person Steve Klabnik    schedule 09.09.2014
comment
Я понимаю вашу точку зрения, но, с другой стороны, тип для самих моих объектов (например, для POST/GET) не зарегистрирован в IANA. В настоящее время я использую application/json, но я мог бы использовать application/vnd-user+json для POST/GET, а затем application/vnd-user-partial+json для PATCH. Почему PATCH отличается от POST/GET и зачем ему более формальный тип? - person Andrey Shchekin; 10.09.2014
comment
Они зарегистрированы, вы обслуживаете их как application/json. Важным отличием является то, что POST и GET ничего не говорят о том, каким должен быть их тип содержимого, а определение PATCH говорит об этом. Это требование необходимо, потому что оно неотъемлемо от того, как работает PATCH: путем внесения каких-либо изменений. - person Steve Klabnik; 10.09.2014
comment
и если вы это сделали, то application/vnd-user-partial+json (хотя на самом деле должно быть application/vnd.user-partial+json) — это пользовательский тип, о котором я упоминал. - person Steve Klabnik; 10.09.2014
comment
Важным отличием является то, что POST и GET ничего не говорят о том, каким должен быть их тип содержимого, но определение PATCH говорит об этом. Однако RFC 5789 не навязывает RFC 6902? Например. если бы я везде использовал XML, мой PATCH определенно не был бы RFC 6902, но все же был бы набором инструкций. - person Andrey Shchekin; 10.09.2014
comment
Да, только если вы используете JSON. Если вы используете XML, вы будете использовать другой формат сравнения. - person Steve Klabnik; 13.09.2014