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

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

  • Создать коллекцию
  • Удалить коллекцию
  • Добавить один элемент в коллекцию
  • Добавить несколько элементов в коллекцию
  • Удалить из коллекции один элемент
  • Удалить несколько элементов из коллекции

Это до тех пор, пока я ушел:

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

==>
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 тоже не кажется здесь)

Ответ 1

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

У коллекции есть url /service/items/. Каждый элемент имеет URL /service/items/<id>.

  • Создание элементов и коллекций - это POST на родительском ресурсе ресурса.
    • Вы можете использовать PUT, если клиент имеет право и возможность генерировать имя или идентификатор ресурса.
  • Удаление элементов и коллекций - это DELETE на самом ресурсе.
  • Добавление нескольких элементов - это либо несколько POST, либо POST с несколькими элементами в родительском (коллекции).
  • Удаление нескольких элементов - это DELETE для каждого ресурса. Я бы обескуражил multi-item DELETE по двум причинам:
    • Массовое удаление - опасная операция (по этой причине я также буду препятствовать DELETE в непустой коллекции).
    • Единственной значимой целью операции является родительская коллекция, что делает объем DELETE асимметричным по отношению к одиночному элементу DELETE.

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

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