我有一个Web API应用程序,我使用下面的url进行批量(数十或数百)插入和更新,只返回OK或Failed。
POST api/v1/products
映射到我的操作:
public HttpResponseMessage PostProducts(PostProductsRequest request)
{
...
}
PostProductsRequest对象包含List类型的Products属性。
如果属性的Id属性存在,我会更新它,否则它会指示插入。
但我只是想知道我是否应该只使用Post for Bulk Inserts和Put for Bulk Updates,不确定。每种方法的最佳实践和优势是什么?
如何为批量插入和更新设计Restful API?
答案 0 :(得分:9)
根据您的要求,可以使用任何一种方法,但这并不意味着它们没有显着差异。 HTTP方法不是CRUD。 PUT或POST不是创建和更新,反之亦然。
PUT 完全用给定的实体替换给定URI的资源,因此它可用于创建和更新,但前提是它包含完整的表示。在PUT之后立即发出的GET请求应该返回相同的资源。表示可能完全相同,但服务可能会添加PUT表示中缺少的默认值。
POST告诉服务器所提供的实体从属于给定URI的资源,并且他们就应该用它做什么达成一致。它可能是任何东西,创建,更新,任何未被HTTP本身标准化的操作。
考虑到这一点,如果您要替换URI标识的整个集合,则使用PUT进行批量插入或更新只是RESTful。这不一定是与该媒体类型相关的整个集合。 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时,操作可以更直接,但它们不是标准化的,您必须为它设计和记录自己的语法。
答案 1 :(得分:6)
我建议使用POST
创建并PUT
进行更新(实际创建或更新indempotent)。
来自RESTful Webservices Cookbook(O'Reilly):
使用POST和集合资源一次创建大量类似资源。 让 客户端包括有关要在请求中创建的资源的信息。分配一个 创建的所有资源的URI,并使用响应将客户端重定向到集合 代码303(见其他)。此资源的表示包括指向所有新资源的链接 创造了资源。
要批量更新或删除大量类似资源,请使用可以使用的单个URI 返回包含有关所有这些资源的信息的表示。提交一个 PUT请求该URI,其中包含有关要更新的资源或a的信息 DELETE请求删除这些资源。 在所有这些情况下,请确保请求的处理是原子的。
答案 2 :(得分:2)
RESTful Web服务中批处理操作最“符合标准”的方法是使用各种“集合”方法之一(即DELETE /mail?&id=0&id=1&id=2
),或者您可以使用batching handler来简化流程
老实说,我使用与您完全相同的模式,除了我使用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
更新:ASP.NET Web API的vNext将有batching built in!
答案 3 :(得分:2)
我正好看着HTTP 1.1 method definition,并提醒了这个问题。
PUT方法请求将所包含的实体存储在提供的Request-URI下。如果Request-URI引用已经存在的资源,则封闭的实体应该被视为驻留在源服务器上的实体的修改版本。 如果Request-URI未指向现有资源,并且该URI能够被请求用户代理定义为新资源,则源服务器可以使用该URI创建资源。 < / p>
这将向我表明,如果你要使用PUT并且有效负载包含一个不存在的资源,并且有足够的信息来创建它,那么应该创建它,因此PUT将是可以创建的批量操作中的正确方法动词&安培;更新资源。