Как создать ресурс коллекции RESTful?

Я пытаюсь создать ресурс "Коллекция предметов". Мне нужно поддержать следующие операции:

  1. Создать коллекцию
  2. Удалить коллекцию
  3. Добавить один элемент в коллекцию
  4. Добавить несколько предметов в коллекцию
  5. Удалить один элемент из коллекции
  6. Удалить несколько элементов из коллекции

Это, насколько я пошел:

Создать коллекцию:

==>
POST /service
Host: www.myserver.com
Content-Type: application/xml
<collection name="items">
 <item href="item1"/>
 <item href="item2"/>
 <item href="item3"/>
</collection>

<==
201 Created
Location: http://myserver.com/service/items
Content-Type: application/xml
...

Удалить коллекцию:

==>
DELETE /service/items

<==
200 OK

Удаление одного элемента из коллекции:

==>
DELETE /service/items/item1
<==
200 OK

Тем не менее, я нахожу поддержку других операций немного сложнее, то есть какие методы я могу использовать для:

  • Добавить один или несколько элементов в коллекцию. (PUT, кажется, здесь не так, как в HTTP 1.1 RFC
  • Удалить несколько элементов из коллекции за одну транзакцию. (DELETE, похоже, тоже не подходит)

5 ответов

Решение

Было бы лучше использовать непозиционный идентификатор, такой как UUID, для элементов коллекции, чтобы избежать проблем, таких как URL-адрес элемента, изменяющегося при удалении элемента, предшествующего ему. (Конечно, вы все еще можете использовать itemN или просто N, до тех пор, пока число всегда остается привязанным к одному и тому же элементу, оставляя пробелы после удалений, но UUID менее запутан.)

Коллекция имеет URL /service/items/, Каждый элемент имеет URL /service/items/<id>,

  1. Создание элементов и коллекций является POST на родительском ресурсе.
    1. Вы можете использовать PUT, если клиент имеет право и возможность генерировать имя или идентификатор ресурса.
  2. Удаление элементов и коллекций - это УДАЛЕНИЕ на самом ресурсе.
  3. Добавление нескольких элементов - это либо несколько POST, либо POST из нескольких элементов на родительском объекте (коллекции).
  4. Удаление нескольких элементов - это УДАЛЕНИЕ на каждом ресурсе. Я бы не рекомендовал УДАЛИТЬ несколько элементов по двум причинам:
    1. Массовое удаление является опасной операцией (по этой причине я бы также не рекомендовал DELETE для непустой коллекции).
    2. Единственной значимой целью операции является родительская коллекция, что делает массовую DELETE асимметричной относительно DELETE из одного элемента.

Если вам действительно нужна возможность массового удаления, предоставьте ее через другой, четко обозначенный API, такой как PURGE /service/items.

Чтобы добавить элементы в коллекцию, вы помещаете их в URL коллекции (http://myserver.com/service/items). в вашем случае у вас уже есть представление "несколько элементов" в XML, просто POST это.

Я не знаю простого способа удалить несколько элементов за одну операцию... возможно, вы могли бы положить объект коллекции со списком идентификаторов для сохранения. идея в том, что PUT обновляет контейнер, поэтому то, что там не было, удаляется. и, я думаю, бесполезно предоставлять все данные, которые вы хотите сохранить, только ссылки на элементы.

Что не так с PUT для создания элемента? Вы цитировали HTTP RFC, но, насколько мне известно, HTTP RFC не исключает использование PUT для создания элемента в вашей коллекции. Если я что-то пропустил, пожалуйста, сделайте конкретную цитату с выдержкой.

Основное различие между PUT и POST для создания элементов:
PUT должен быть идемпотентной операцией; POST нет.

Для удаления нескольких элементов в одной транзакции вы можете отправить DELETE на URL, который указывает диапазон (/service/items/13-20, или вы можете отправить DELETE в / service / items и использовать заголовок HTTP Range (см. RFC2616 sec 14.35.2.) Обычно заголовок диапазона создается для указания байтового диапазона и используется в запросе GET, но ваш ресурс может определить значение RANGE в DELETE.

Почему бы не использовать спецификацию AtomPub и придерживаться написанных там решений? Таким образом, новые клиенты могут легко потреблять ваши данные (используя простые библиотеки GData...), и такие вещи, как потоки данных с постраничной передачей и синтаксис GET/POST/PUT/DELETE, четко определены. Просто мои $.02.

Используйте Content-Type /text/uri-list и управляйте PUT,GET,PATCH,DELETE списком ссылок на ресурсы, которые вы хотите собрать.

Формат PATCH, который вам нужен, может быть очень простым: просто добавьте "+ " или "- " модальность изменения, которое каждое URI вносит в коллекцию. К сожалению, этот тип носителя, который может быть назван text / uri-list-update, официально не зарегистрирован, насколько мне известно.

Другие вопросы по тегам