繁体   English   中英

如何为批量插入和更新设计一个Restful API?

[英]How to Design a Restful API for Bulk Inserts and Updates?

我有一个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?

根据您的要求,可以使用任何一种方法,但这并不意味着它们没有显着差异。 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]}

但是,如果您有一个过滤器约束,您可以应用于将在上面的GET上返回空集合的/api/products ,那么只有将新产品用于该过滤资源才能进行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 return:

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

这可能看起来很复杂,有时看起来最好使用POST而不是PUT,但请记住,上面的整个操作都是标准化的。 它正在使用PUT,就像它打算使用的那样。 使用POST时,操作可以更简单,但它们不是标准化的,您必须为它设计和记录自己的语法。

我建议使用POST来创建和PUT进行更新(实际创建或更新,因为它是无效的 )。

来自RESTful Webservices Cookbook (O'Reilly):

使用POST和集合资源一次创建许多类似的资源。 让客户端包含有关要在请求中创建的资源的信息。 为所有创建的资源分配URI,并使用响应代码303将客户端重定向到集合(请参阅其他)。 此资源的表示包括指向所有新创建的资源的链接。

要批量更新或删除大量类似资源,请使用单个URI,该URI可返回包含有关所有这些资源的信息的表示。 向该URI提交PUT请求,其中包含有关要更新的资源的信息或删除这些资源的DELETE请求。 在所有这些情况下,请确保请求的处理是原子的。

RESTful Web服务中批处理操作最“符合标准”的方法是使用各种“集合”方法之一(即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

更新 :ASP.NET Web API的vNext将内置批处理

我刚刚看到HTTP 1.1方法定义 ,并提醒了这个问题。

PUT方法请求将所包含的实体存储在提供的Request-URI下。 如果Request-URI引用已经存在的资源,则封闭的实体应该被视为驻留在源服务器上的实体的修改版本。 如果Request-URI未指向现有资源,并且该URI能够被请求用户代理定义为新资源,则源服务器可以使用该URI创建资源。

这将向我表明,如果你使用PUT并且有效负载包含一个不存在的资源,并且有足够的信息来创建它,那么它应该被创建,因此PUT将是批量操作中可以创建和更新资源的正确方法动词。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM