Ответ 1
Пока результат PUT является полной заменой от понимания клиентом ресурса (т.е. предыдущие значения для тех свойств, которые не были переданы, не влияют на их значение после PUT), он должен преуспеть. Тем не менее, это немного сбивает с толку, так как многие люди склонны равнозначно использовать это использование PUT с семантикой обновления на уровне поля (а не полной заменой).
Несмотря на то, что здесь нет никаких ограничений на ограничения REST, вероятно, лучше всего передать все значения и не прибегать к значениям по умолчанию для сервера, поскольку это поможет сохранить прямую совместимость. Значения по умолчанию могут меняться со временем, поэтому обычно их следует избегать.
Однако ваш пример ссылок не относится к тому, чтобы не передавать значения по умолчанию, поэтому это не хороший пример "неполного представления". Скорее, ссылки не являются частью клиентского представления ресурса на сервере. Я думаю, что вы добавили еще одну концепцию в микс: свойства, которые возвращаются только с сервера клиенту. Это то, о чем я говорил в другой теме, которая вызвала этот пост.
То, о чем я говорю, не является неполным представлением; это другое представление. Вы действительно имеете дело с двумя разными типами носителей (т.е. Представлениями), описывающими один и тот же ресурс. Один происходит от клиента (мы будем называть его application/vnd.example.api.client), а другой - с сервера (application/vnd.example.api.server). Они не могут быть явно помечены как таковые, но это, по крайней мере, неявно, что происходит. Поэтому, поскольку они представляют собой два разных типа медиа, они выражают разные вещи о том же ресурсе.
Поскольку вы упомянули HAL, считайте, что клиент обычно не отправляет сообщение на сервер приложения типа носителя /hal + json. Посмотрите на подтверждение от HALTalk для примера. Ожидаемый тип содержимого - application/json, а не application/hal + json. И, если вы посмотрите на примерный пост, в нем ничего нет HAL-ish. Нет ссылок, нет внедренных объектов и т.д. Но... если вы затем получите URL-адрес, возвращенный из заголовка Location, возвращенного из этого POST, он будет, полагая, что ваш клиент принимает HAL через JSON, возвращает ответ типа application/hal + json (т.е. пользователь со ссылками). Два разных типа медиа, два разных представления одного и того же ресурса.
Итак, позвольте мне украсить ваш пример заголовками Accept и Content-Type, чтобы проиллюстрировать мою точку.
Запрос
PUT /api/users/1 HTTP/1.1
Content-Type: application/vnd.example.api.client+json
{'username': 'joeydoey',
'email': '[email protected]'}
ответ
200 OK
Content-Type: application/hal+json;profile=application/vnd.example.api.server
{'id': 1,
'username': 'joeydoey',
'email': '[email protected]',
'password_hash': '9039dmk38f84uf4029i339kf32f0932i',
'_links': {'self': {'href': 'http://foo.bar.com/api/users/1'}}
}
Большинство систем не обращаются к этому количеству деталей, чтобы описать их типы носителей. Обычно он просто обрамлен более общим типом (например, application/json или только один пользовательский тип носителя). Однако ничто из этого не меняет тот факт, что, хотя он является одним и тем же базовым ресурсом, это два разных представления. Есть смысл?