Должен ли я разрешить отправку полных структур при использовании PUT для обновлений в REST API или нет? - PullRequest
3 голосов
/ 27 апреля 2010

Я занимаюсь разработкой REST API, и мне интересно, каков рекомендуемый способ обработки обновлений ресурсов. В частности, я бы разрешил обновления через ресурс PUT на ресурсе, но что я должен разрешить в теле запроса PUT?

  1. Всегда полная структура ресурса?
  2. Всегда подраздел (что изменилось) структуры ресурса?
  3. Комбинация обоих?

Например, взять ресурс http://example.org/api/v1/dogs/packs/p1. GET на этом ресурсе даст следующее:

Request:
GET http://example.org/api/v1/dogs/packs/p1
Accept: application/xml

Response:
<pack>
  <owner>David</owner>
  <dogs>
    <dog>
      <name>Woofer</name>
      <breed>Basset Hound</breed>
    </dog>
    <dog>
      <name>Mr. Bones</name>
      <breed>Basset Hound</breed>
    </dog>
  </dogs>
</pack>

Предположим, я хочу добавить собаку (Sniffers the Basset Hound) в стаю, я бы поддержал либо:

Request:
PUT http://example.org/api/v1/dogs/packs/p1
<dog>
  <name>Sniffers</name>
  <breed>Basset Hound</breed>
</dog>

Response:
HTTP/1.1 200 OK

или

Request:
PUT http://example.org/api/v1/dogs/packs/p1
<pack>
  <owner>David</owner>
  <dogs>
    <dog>
      <name>Woofer</name>
      <breed>Basset Hound</breed>
    </dog>
    <dog>
      <name>Mr. Bones</name>
      <breed>Basset Hound</breed>
    </dog>
    <dog>
      <name>Sniffers</name>
      <breed>Basset Hound</breed>
    </dog>
  </dogs>
</pack>

Response:
HTTP/1.1 200 OK

или оба? Если рекомендуется поддержка обновлений через подразделы структуры, как бы я обрабатывал удаления (например, когда собака умирает)? Через параметры запроса?

Ответы [ 2 ]

7 голосов
/ 27 апреля 2010

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

Однако вы можете рассмотреть следующие вопросы:

  • использовать пространства имен XML или другие средства управления версиями (например,? Version = 2) вне пути URL
  • POST собака, которую вы хотите добавить в / dogs / packs / p1. POST по определению создает подчиненный ресурс, чтобы добавить собаку в пакет.
  • Немного обновите ваши URL. Мне кажется, вы действительно хотите иметь / dogs / 1234, / dogs / 1235 и так далее, а затем / packs / p1, / ​​packs / p2. Тогда вы также можете просто отправить POST <dog id="1"> в пакет.

Имейте в виду, что REST требует от вас правильной идентификации ресурсов. Стая на самом деле не является подчиненным ресурсом для собак, и каждая собака должна иметь своего рода уникальный идентификатор. Затем при доступе к / packs / p1 / 1234 вы, вероятно, захотите перенаправить на / dogs / 1234. Или же вы просто не сделаете этот URL доступным, несмотря на то, что принимаете POST-запрос подчиненных ресурсов к соответствующему пакету.

Чем больше я об этом думаю, тем больше смысла в подходе POST. Возможно, у вас даже может быть ресурс / packs / p1 / dogs / для всех собак, отдельно от стаи. Затем вы можете поместить такие вещи, как информация о владельце и т. Д. В / packs / p1, ПОЛУЧИТЬ список всех собак через / packs / p1 / dogs / (который должен содержать список URL для каждой собаки в стае Например, / packs / p1 / dogs / 1234, см. HATEOAS ), добавьте новую собаку в пакет, поместив POST в / packs / p1 / dogs /, и удалите собаку с помощью DELETEing / packs / p1 / собаки / 1235. Каждая собака может быть либо полным представлением, возможно, даже с перенаправлением на / dogs / 1234 и т. Д., Либо другим представлением собаки в контексте этого пакета, но опять же со ссылкой на «полную» собаку. Зависит от того, как вы хотите представлять одну собаку в стае, и это, конечно, также повлияет на что вы на самом деле POST для / packs / p1 / dogs /. Полная собака чувствует себя неправильно, на самом деле это просто удостоверение личности, как я показал выше, возможно, с дополнительными данными, относящимися к отношениям с пакетом.

2 голосов
/ 27 апреля 2010

PUT эффект «заменить». Так что да, вам нужно предоставить полное представление с запросом PUT.

Если вы хотите обновить только части ресурса, у вас есть следующие варианты:

  • Определите ресурс, который представляет часть и PUT там
  • Использовать POST для подресурса и иметь Сервер вернул 303 см. Другое с заголовок Location, указывающий на основной ресурс
  • Использовать PATCH

В вашем случае, вероятно, было бы лучше сделать собак субресурсом (набором собак из стаи) и POST к этому обычным способом POST-as-append

...