RESTful способ создать несколько элементов в одном запросе
Я работаю над небольшой клиент-серверной программой для сбора заказов. Я хочу сделать это "ОТЛИЧНЫМ (полным) способом".
Что я хочу сделать, это:
Соберите все строки заказа (продукт и количество) и отправьте полный заказ на сервер
На данный момент я вижу два варианта сделать это:
- Отправьте каждую строку заказа на сервер: POST кол-во и product_id
На самом деле я не хочу этого делать, потому что я хочу ограничить количество запросов к серверу, поэтому вариант 2:
- Соберите все строки заказа и отправьте их на сервер сразу.
Как мне реализовать вариант 2? у меня есть пара идей: обернуть все строки заказа в объект JSON и отправить их на сервер или использовать массив для публикации строк заказа.
Это хорошая идея или хорошая практика для реализации варианта 2, и если да, то как мне это сделать.
Что такое хорошая практика?
7 ответов
Я считаю, что еще один правильный способ сделать это - создать еще один ресурс, представляющий вашу коллекцию ресурсов. Пример, представьте, что у нас есть конечная точка, как /api/sheep/{id}
и мы можем отправить /api/sheep
создать овечий ресурс.
Теперь, если мы хотим поддержать массовое создание, мы должны рассмотреть новый ресурс стада в /api/flock
(или же /api/<your-resource>-collection
если вам не хватает лучшего значимого имени). Помните, что ресурсы не нужно сопоставлять с вашей базой данных или моделями приложений. Это распространенное заблуждение.
Ресурсы - это представление более высокого уровня, не связанное с вашими данными. Работа с ресурсом может иметь значительные побочные эффекты, такие как отправка предупреждения пользователю, обновление других связанных данных, запуск долгоживущего процесса и т. Д. Например, мы можем отобразить файловую систему или даже Unix ps
Команда в качестве REST API.
Я думаю, можно с уверенностью предположить, что использование ресурса может также означать создание нескольких других объектов в качестве побочного эффекта.
Хотя массовые операции (например, пакетное создание) важны во многих системах, они формально не рассматриваются в стиле архитектуры RESTful.
Я обнаружил, что отправка коллекции, как вы предлагали, в основном работает, но возникают проблемы, когда вам необходимо сообщать о сбоях в ответ на такой запрос. Такие проблемы усугубляются, когда происходит несколько сбоев по разным причинам или когда сервер не поддерживает транзакции. Я предлагаю вам следующее: если нет проблем с производительностью, например, когда поставщик услуг находится в локальной сети (не в глобальной сети) или данные относительно малы, стоит отправить 100 запросов POST на сервер. Будьте проще, начните с отдельных запросов и, если у вас есть проблемы с производительностью, попробуйте оптимизировать.
Facebook объясняет, как это сделать: https://developers.facebook.com/docs/graph-api/making-multiple-requests
Простые пакетные запросы
Пакетный API принимает массив логических HTTP-запросов, представленных в виде массивов JSON - каждый запрос имеет метод (соответствующий HTTP-методу GET/PUT/POST/DELETE и т. Д.),Lative_url (часть URL-адреса после graph.facebook.com), необязательный массив заголовков (соответствующий заголовкам HTTP) и необязательное тело (для запросов POST и PUT). Пакетный API возвращает массив логических HTTP-ответов, представленных в виде массивов JSON - каждый ответ имеет код состояния, необязательный массив заголовков и необязательное тело (которое является строкой в кодировке JSON).
Ваша идея мне кажется действительной. Реализация зависит от ваших предпочтений. Вы можете использовать JSON или просто параметры для этого (массив "order_lines[]") и сделать
POST /orders
Поскольку вы собираетесь создавать больше ресурсов за одно действие (порядок и его строки), жизненно важно проверять каждый из них и сохранять их только в том случае, если все они проходят проверку, т.е. Вы должны сделать это в транзакции.
Я на самом деле боролся с этим в последнее время, и вот к чему я работаю.
Если POST, который добавляет несколько ресурсов, успешен, верните 200 OK (я рассматривал 201, но пользователь в конечном итоге не получает доступ к созданному ресурсу) вместе со страницей, которая отображает все добавленные ресурсы, либо в режиме чтения Только для редактирования или моды. Например, пользователь может выбрать и отправить несколько изображений в галерею, используя форму, содержащую только один входной файл. Если запрос POST завершается успешно, пользователю предоставляется набор форм для каждого созданного представления ресурса изображения, который позволяет им указать более подробную информацию о каждом (имя, описание и т. Д.).
В случае, если не удается создать один или несколько ресурсов, обработчик POST прерывает всю обработку и добавляет каждое отдельное сообщение об ошибке в массив. Затем возвращается конфликт 419, и пользователь перенаправляется на страницу с ошибкой конфликта 419, на которой представлено содержимое массива ошибок, а также обратно к отправленной форме.
Я думаю, что лучше отправлять отдельные запросы в рамках одного соединения. Конечно, ваш веб-сервер должен его поддерживать
Вам не нужно отправлять заголовки HTTP для 100 строк заказа. Вы также не хотите генерировать больше запросов, чем необходимо.
Отправьте весь заказ в одном объекте JSON на сервер по адресу: server/order или server/order/new. Возвратите что-то, что указывает на: server/order/order_id
Также рассмотрите возможность использования CREATE PUT вместо POST