RESTful способ создания нескольких элементов в одном запросе

Я работаю над небольшой клиентской программой для сбора заказов. Я хочу сделать это с помощью метода "REST (полный)".

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

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

В данный момент я вижу два варианта:

  • Отправьте каждую строку заказа на сервер: POST qty и product_id

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

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

POST /orders

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

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

Я считаю, что Pipelining - это ответ, который вам нужен, который описан в предыдущей ссылке "Одно соединение".

Ответ 8

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

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

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