C# 如何为批量插入和更新设计Restful API?

C# 如何为批量插入和更新设计Restful API?,c#,asp.net,rest,asp.net-web-api,C#,Asp.net,Rest,Asp.net Web Api,我有一个Web API应用程序,我使用下面的url进行批量(数十或数百)插入和更新,这些插入和更新返回正常或失败 POST api/v1/products 已映射到我的操作: public HttpResponseMessage PostProducts(PostProductsRequest request) { ... } PostProductsRequest对象包含List类型的Products属性 如果某个属性的Id属性存在,我将更新它,否则它将指示插入 但我只是想知道我是否应该

我有一个Web API应用程序,我使用下面的url进行批量(数十或数百)插入和更新,这些插入和更新返回正常或失败

POST api/v1/products
已映射到我的操作:

public HttpResponseMessage PostProducts(PostProductsRequest request)
{

...
}
PostProductsRequest对象包含List类型的Products属性

如果某个属性的Id属性存在,我将更新它,否则它将指示插入

但我只是想知道我是否应该只使用Post进行批量插入,而使用Put进行批量更新,不确定。每种方法的最佳实践和优势是什么

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

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的下一页将有

我建议使用
POST
创建和
PUT
更新(实际创建或更新)

来自(O'Reilly):

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

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


我只是碰巧看到了这张照片,我想起了这个问题

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


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

根据您的需求,可以使用任何一种方法,但这并不意味着它们没有显著差异。HTTP方法不是CRUD。PUT或POST不是创建和更新,或者相反

PUT完全使用提供的实体替换给定URI处的资源,因此它可以用于创建和更新,但前提是它包含完整表示。在PUT之后立即发出的GET请求应返回相同的资源。表示可能完全相同,但服务可以添加PUT’ed表示中缺少的默认值

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]}
{'products': [product4, product5, product6]}
GET/api/products?partner=y
返回:

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

这可能看起来很复杂,有时看起来使用POST而不是PUT更好,但请记住,上面的整个操作是标准化的。它使用的PUT与预期的完全一致。POST的操作可能更简单,但它们没有标准化,您必须为其设计并记录自己的语法。

我的第一个想法是:如果它有效,就不要修复它。
PUT
POST
之间的差异太小,无法在这里产生影响。这通常是正确的,但POST和PUT表示不同的意图。你可以把PUT称为