Создавайте один и несколько ресурсов с помощью ненадежного HTTP - программирование
Подтвердить что ты не робот

Создавайте один и несколько ресурсов с помощью ненадежного HTTP

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

POST /categories

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

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

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

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

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

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

POST /bulk

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

4b9b3361

Ответ 1

В истинном REST вы, вероятно, должны ПОСТИТЬ это в нескольких отдельных вызовах. Причина в том, что каждый из них приведет к новому представлению. Как бы вы ожидали получить обратное в противном случае.

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

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

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

Вот аналогичный вопрос

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

Ответ 2

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

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

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

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

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

Ответ 3

Нет ничего плохого в создании нескольких ресурсов сразу с помощью POST (просто не пытайтесь использовать PUT). Это не "un-REST-ful", особенно если вы создаете представление для самой объемной операции. Я предлагаю вам создать ресурс индекса одновременно с созданием отдельных ресурсов и вернуть ему "303 See Other". Тогда это представление индекса будет содержать ссылки на все созданные ресурсы (и, возможно, информацию об ошибках, если какой-либо из них не удался).

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."}]

Ответ 4

В вашем случае я также перейду к ресурсу ресурсов. Но шаблон, который я хотел бы предложить, следующий и, с моей точки зрения, наиболее естественный: работа с кодом принятого статуса 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, вероятно, из-за недостающего ресурса.