RESTful способ создать несколько элементов в одном запросе - PullRequest
108 голосов
/ 04 января 2009

Я работаю над небольшой клиент-серверной программой для сбора заказов. Я хочу сделать это "ОТЛИЧНЫМ" способом.

Что я хочу сделать, это:

Соберите все строки заказа (продукт и количество) и отправьте полный заказ на сервер

На данный момент я вижу два варианта сделать это:

  1. Отправка каждой строки заказа на сервер: POST кол-во и product_id

На самом деле я не хочу этого делать, потому что я хочу ограничить количество запросов к серверу, поэтому вариант 2:

  1. Соберите все строки заказа и отправьте их на сервер сразу.

Как мне реализовать вариант 2? у меня есть пара идей: Оберните все строки заказа в объект JSON и отправьте их на сервер или используйте массив для размещения строк заказа.

Это хорошая идея или хорошая практика для реализации варианта 2, и если да, то как мне это сделать.

Что такое хорошая практика?

Ответы [ 7 ]

60 голосов
/ 18 ноября 2015

Я полагаю, что еще один правильный способ достичь этого - создать еще один ресурс, представляющий вашу коллекцию ресурсов. Например, представьте, что у нас есть конечная точка, такая как /api/sheep/{id}, и мы можем POST к /api/sheep, чтобы создать овечий ресурс.

Теперь, если мы хотим поддержать массовое создание, мы должны рассмотреть новый ресурс скопления в /api/flock (или /api/<your-resource>-collection, если вам не хватает лучшего значащего имени). Помните, что ресурсам не нужно сопоставлять вашу базу данных или модели приложений . Это распространенное заблуждение.

Ресурсы являются представлением более высокого уровня, не связанным с вашими данными. Работа с ресурсом может иметь значительные побочные эффекты, такие как отправка предупреждения пользователю, обновление других связанных данных, запуск долгоживущего процесса и т. Д. Например, мы можем отобразить файловую систему или даже команду unix ps как REST API.

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

41 голосов
/ 08 января 2009

Хотя массовые операции (например, пакетное создание) важны во многих системах, они формально не рассматриваются в стиле архитектуры RESTful.

Я обнаружил, что отправка коллекции, как вы предлагали, в основном работает, но возникают проблемы, когда вам необходимо сообщить о сбоях в ответ на такой запрос. Такие проблемы усугубляются, когда происходит несколько сбоев по разным причинам или когда сервер не поддерживает транзакции. Я предлагаю вам, если нет проблем с производительностью, например, когда поставщик услуг находится в локальной сети (не в глобальной сети) или данные относительно малы, стоит отправить 100 запросов POST на сервер. Будьте проще, начните с отдельных запросов и, если у вас проблемы с производительностью, попробуйте оптимизировать.

10 голосов
/ 16 сентября 2014

Facebook объясняет, как это сделать: https://developers.facebook.com/docs/graph-api/making-multiple-requests

Простые пакетные запросы

Пакетный API принимает массив представленных логических HTTP-запросов. как массивы JSON - у каждого запроса есть метод (соответствующий HTTP метод GET / PUT / POST / DELETE и т. д.) URL после graph.facebook.com), необязательный массив заголовков (соответствующий в заголовки HTTP) и необязательное тело (для запросов POST и PUT). Пакетный API возвращает массив логических HTTP-ответов, представленных в виде JSON-массивы - каждый ответ имеет код состояния, необязательные заголовки массив и необязательное тело (которое является строкой в ​​кодировке JSON).

8 голосов
/ 04 января 2009

Ваша идея мне кажется действительной. Реализация зависит от ваших предпочтений. Вы можете использовать JSON или просто параметры для этого (массив "order_lines []") и сделать

POST /orders

Поскольку вы собираетесь создавать больше ресурсов одновременно за одно действие (порядок и его строки), жизненно важно проверять каждый из них и сохранять их только в том случае, если все они проходят проверку, т.е. Вы должны сделать это в транзакции.

6 голосов
/ 25 июня 2009

Полагаю, лучше отправлять отдельные запросы в пределах одного соединения . Конечно, ваш веб-сервер должен поддерживать его

5 голосов
/ 24 октября 2013

Я на самом деле боролся с этим в последнее время, и вот к чему я работаю.

Если POST, который добавляет несколько ресурсов, завершается успешно, верните 200 OK (я рассматривал 201, но пользователь в конечном итоге не получает доступ к созданному ресурсу) вместе со страницей, которая отображает все добавленные ресурсы, либо только для чтения или редактируемым способом. Например, пользователь может выбрать и отправить несколько изображений в галерею, используя форму, содержащую только один файл ввода. Если запрос POST завершается успешно, пользователю предоставляется набор форм для каждого созданного представления ресурса изображения, позволяющий ему указать более подробную информацию о каждом (имя, описание и т. Д.).

В случае, если не удается создать один или несколько ресурсов, обработчик POST прерывает всю обработку и добавляет каждое отдельное сообщение об ошибке в массив. Затем возвращается конфликт 419, и пользователь перенаправляется на страницу ошибки конфликта 419, на которой представлено содержимое массива ошибок, а также обратно в отправленную форму.

0 голосов
/ 04 января 2009

Вы не хотите отправлять заголовки HTTP для 100 строк заказа. Вы также не хотите генерировать больше запросов, чем необходимо.

Отправить весь заказ в одном объекте JSON на сервер: server / order или server / order / new. Возвратите что-то, что указывает на: server / order / order_id

Также рассмотрите возможность использования CREATE PUT вместо POST

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...