Создайте один и несколько ресурсов, используя спокойный HTTP

На моем сервере API я определил этот маршрут:

POST /categories

Чтобы создать одну категорию, вы делаете:

POST /categories {"name": "Books"}

Я думал, что если вы хотите создать несколько категорий, то вы можете сделать:

POST /categories [{"name": "Books"}, {"name": "Games"}]

Я просто хочу подтвердить, что это хорошая практика для Restful HTTP API.

Или нужно иметь

POST /bulk

для того, чтобы позволить им делать какие-либо операции одновременно (создание, чтение, обновление и удаление)?

 wingy20 июн. 2012 г., 16:45
Ничего .. но если вы хотите создать 1000 ресурсов, я сомневаюсь, что вы хотите сделать 1000 туда-обратно, а не 1. Меньше времени, меньше денег, меньше кода.
 Neikos20 июн. 2012 г., 16:30
Что мешает тебе называть это не раз?

Ответы на вопрос(4)

чтобы выполнить массовую операцию, которую вы POST активируете (это будет неидемпотентным, поэтому POST - правильный глагол), но есть некоторые предостережения:

Вы делаете несколько ресурсов, поэтому вам нужно ответить несколькими URL-адресами. Это означает, что вы не можете использовать шаблон перенаправления: вам придется отправить список URL-адресов обратно в какой-либо форме.

У вас есть проблема в том, что массовые операции часто не очень заметны. Обнаружение - одна из самых важных вещей в RESTfulness, поскольку это означает, что кто-то может прийти и выяснить, как написать клиент без большой помощи со стороны автора сервера.

Решение частичных сбоев при массовых операциях остается проблематичным. Это проблема и для любой другой парадигмы (я наблюдал, как люди связывают себя узлами над этим при работе с расширениями для SOAP), так что это не удивительно, но если вы не можете Гарантия что все творения будут работать, вам нужно будет решить, что произойдет, если вы создадите один ресурс, а второй не сможете. (Кроме того, если массовый запрос требует выполнения третьего запроса, вы можете попробовать его?)

Самый простой подход - просто поддерживать одно создание на запрос; это гораздо легче понять правильно и лучше понять со всех сторон.

вероятно, следует размещать это в нескольких отдельных вызовах. Причина в том, что каждый из них приведет к новому представлению. Как вы ожидаете получить это обратно в противном случае.

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

POST -> New Resource Location
POST -> New Resource Location
...

Однако, если вам нужна большая часть, создайте большую. По возможности будьте догматичными, но если нет, то прагматизм выполняет свою работу. Если вы слишком зациклены на догматизме, то ничего не сделаете.

Вот похожий вопрос

Вот тот, который предлагает HTTP Pipelining, чтобы сделать это более эффективным

 s.m.01 авг. 2013 г., 15:03
+ 1 для "прагматизм делает работу". Я также создаю API и, имея тысячи ресурсов, думаю, массовое создание превосходит один POST на ресурс.

ью POST (только не пытайтесь сделать это с помощью PUT). Это не «не REST-ful», особенно если вы создаете представление для самой массовой операции. Я предлагаю вам создать индексный ресурс в то же время, когда вы создаете отдельные ресурсы, и возвращать ему «303 См. Другие». Это представление индекса будет содержать ссылки на все созданные ресурсы (и, возможно, информацию об ошибке, если какой-либо из них потерпит неудачу).

POST /categories/uploads/
[{"name": "Books"}, {"name": "Games"}]

    303 See Other
    Location: /categories/uploads/321/

(на самом деле, теперь, когда я думаю об этом, 201 может быть лучше, чем 303)

GET /categories/uploads/321/

    200 OK
    Content-Type: application/json

    [{"name": "Books", "link": "/categories/Books/"},
     {"name": "Games", "error": "The 'Games' category already exists."}]
 wingy21 июн. 2012 г., 02:32
Почему я не могу вернуть созданные ресурсы в ответе POST напрямую?
 Markon10 янв. 2014 г., 11:58
@ fumanchu: я не совсем согласен. Прочитайте это: Stackoverflow.com / а / 1829913. Кроме того, Restful Web Services говорит: «Entity-body: Должен описывать и ссылаться на вновь созданный ресурс. Представление этого ресурса приемлемо, если вы используете заголовок Location, чтобы сообщить клиенту, где этот ресурс действительно живет».
 fumanchu21 июн. 2012 г., 16:06
Потому что это RPC, а не REST. Возвращенные представления, вероятно, не будут кэшироваться; даже если вам удастся найти кеш, который кеширует ответы POST, он не будет кэшироваться в URI, который идентифицирует ресурс (очевидно, он идентифицирует создание ресурса).
 fumanchu21 июн. 2012 г., 19:34
Похоже, Джулиан смотрит через мое плечо;) Trac.tools.ietf.org / WG / httpbis / ПРОФ / билет / 347

который я бы предложил, является следующим и, насколько я понимаю, наиболее естественным: работа с кодом статуса 202 «Принят».

Идея массового запроса заключается в том, что сервер не должен быть вынужден отвечать немедленно, поскольку это будет означать, что клиент должен дождаться завершения массового запроса.

Вот образец:

POST /bulk [{"name": "Books"}, {"name": "Games"}]
202 Accepted | Location: /bulk/processing/status/resourceId

GET /bulk/processing/status/resourceId
entry = "REST in peace" | completed | 0 errors | /categories/category/resourceId
entry = "Walking dead" | processing | 0 errors ->

Так, клиент отправляет большую часть информации на сервер. Сервер просто принимает их с 202, который не дает гарантии о состоянии обработки во время ответа. Но сервер также предоставляет ссылку на ресурс статуса. Здесь клиент может взглянуть на каждый из созданных ресурсов и состояние обработки. По окончании клиент может получить доступ к ресурсу по указанной ссылке. Случаи ошибок могут быть идентифицированы клиентом, а ошибочные данные могут быть повторно отправлены PUT на завершенном ресурсе.

Наконец, хороший совет, которым я обычно следую, заключается в следующем: всякий раз, когда вы сталкиваетесь с ресурсом в своем дизайне, который не может быть сопоставлен с функцией HTTP, это, вероятно, из-за отсутствующего ресурса.

Ваш ответ на вопрос