Подтвердить что ты не робот

Как создать надежный API для массовых вложений и обновлений?

У меня есть приложение веб-API, и я использую приведенный ниже URL для вложенных и насыщенных (десятков или сотен) вставок и обновлений, которые возвращают только ОК или Сбой.

POST api/v1/products

который отображается на мое действие:

public HttpResponseMessage PostProducts(PostProductsRequest request)
{

...
}

Объект PostProductsRequest содержит свойство Products типа List.

Если свойство Id существует для свойства, я обновляю его, иначе оно указывает на вставку.

Но мне просто интересно, следует ли использовать Post для Bulk Inserts и Put for Bulk Updates, но не уверен. Какая наилучшая практика и преимущества каждого подхода?

Как создать надежный API для массовых вложений и обновлений?

4b9b3361

Ответ 1

Любой метод может использоваться в зависимости от ваших реквизитов, но это не означает, что они не имеют существенных различий. Методы HTTP не являются CRUD. PUT или POST не создают и не обновляют, а наоборот.

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

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

С учетом этого массовая вставка или обновление с PUT является только RESTful, если вы заменяете всю коллекцию, идентифицированную URI. Это не обязательно должна быть вся ваша коллекция, связанная с этим типом мультимедиа. У URI может быть запрос, разрезающий набор данных, и вы выполняете массовую операцию только на этом фрагменте.

Например, если у вас есть следующий ресурс коллекции:

GET /api/products

Представлено:

{'products': [product1, product2, product3]}

И вы хотите добавить еще три продукта, массовая операция с PUT должна была бы добавить ваши новые продукты в существующую и отправить всю коллекцию обратно:

PUT /api/products

{'products': [product1, product2, product3, product4, product5, product6]}

Однако, если у вас есть ограничение на фильтр, вы можете применить к /api/products, который вернет пустую коллекцию в GET выше, тогда было бы хорошо выполнить PUT только с новыми продуктами для этого фильтрованного ресурса. Например, предположим, что вышеуказанные продукты могут быть отфильтрованы атрибутом партнера, у них есть партнер x, и вы добавляете для партнера y:

В этом случае вам будет хорошо:

PUT /api/products?partner=y

{'products': [product4, product5, product6]}

И после этого возвращается GET /api/products:

{'products': [product1, product2, product3, product4, product5, product6]}

Пока GET /api/products?partner=x возвращает:

{'products': [product1, product2, product3]}

И GET /api/products?partner=y возвращает:

{'products': [product4, product5, product6]}

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

Ответ 2

Я бы рекомендовал использовать POST для создания и PUT для обновления (на самом деле создавать или обновлять, так как это indempotent).

Из RESTful Webservices Cookbook (O'Reilly):

Используйте POST и ресурс коллекции, чтобы создать сразу несколько похожих ресурсов. Позволять клиенты включают информацию о ресурсах, которые будут созданы в запросе. Назначить URI для всех созданных ресурсов и перенаправить клиента в коллекцию с использованием ответа код 303 (см. раздел "Прочее" ). Представление этого ресурса включает ссылки на все созданных ресурсов.

Чтобы обновить или удалить несколько похожих ресурсов навалом, используйте единый URI, который может вернуть представление, содержащее информацию обо всех этих ресурсах. Отправить PUT запрашивает этот URI с информацией о ресурсах, которые необходимо обновить, или DELETE, чтобы удалить эти ресурсы. Во всех этих случаях убедитесь, что обработка запроса является атомарной.

Ответ 3

Самый "совместимый с стандартами" способ для пакетных операций в веб-службах RESTful - использовать один из различных подходов "сбор" (т.е. DELETE /mail?&id=0&id=1&id=2), или вы можете использовать пакетный обработчик просто для процесса.

Честно говоря, я использую тот же шаблон, что и вы, за исключением того, что я использую POST для создания объекта и PUT только для обновлений (что является стандартным способом его выполнения). Также POST должен возвращать 201 - Создан вместе с созданным объектом, а PUT должен возвращать 204 - Нет содержимого без данных, если операция завершается успешно. Конечно, поскольку вы делаете массовое создание, вы можете не возвращать массив вновь созданных объектов с помощью POST.

Подводя итог этому:

POST api/products
  |
  |---> Success: 201 [NewObject1, NewObject2, ...]
  |---> Failure: Relevant error code as to why the operation failed

PUT api/products
  |
  |---> Success: 204
  |---> Failure: Relevant error code as to why the operation failed

Обновить: vNext веб-API ASP.NET будет пакетное создание!

Ответ 4

Я просто случайно посмотрел на определение метода HTTP 1.1 и был напомнен об этом вопросе.

Метод PUT запрашивает, чтобы закрытый объект хранился в запрошенном Request-URI. Если Request-URI ссылается на уже существующий ресурс, закрытый объект СЛЕДУЕТ считаться модифицированной версией той, которая находится на исходном сервере. Если Request-URI не указывает на существующий ресурс и что URI может быть определен как новый ресурс запрашивающим пользовательским агентом, исходный сервер может создать ресурс с этим URI.

Это укажет мне, что если вы должны использовать PUT и полезную нагрузку, содержащую не существующий ресурс с достаточной информацией для его создания, тогда он должен быть создан, и поэтому PUT будет правильным глаголом метода в массовой операции, которая может создать и обновления ресурсов.