Как создать ресурс коллекции 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, пока не зарегистрирован, насколько мне известно.