C# 如何在Web API中更新集合?
我有一个基本的C# 如何在Web API中更新集合?,c#,rest,asp.net-web-api,url-routing,asp.net-core-webapi,C#,Rest,Asp.net Web Api,Url Routing,Asp.net Core Webapi,我有一个基本的Order-OrderItem情况,我正在努力在一个请求中更新项目(或者我是否应该?),让我解释一下,最后我会问这个问题 型号: public class Order { public int OrderId { get; set; } public string CustomerId { get; set; } public bool IsVoided { get; set; } public List<OrderItem> Item
Order
-OrderItem
情况,我正在努力在一个请求中更新项目(或者我是否应该?),让我解释一下,最后我会问这个问题
型号:
public class Order
{
public int OrderId { get; set; }
public string CustomerId { get; set; }
public bool IsVoided { get; set; }
public List<OrderItem> Items { get; set; }
}
public class OrderItem
{
public int OrderItemId { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public int Price { get; set; }
}
Order
的属性,如isvoid
(但不是项目):[PATCH]/api/orders/{orderId}
订单的项目(一次多个项目)
,有效负载:[POST]/api/orders/{orderId}/items
{“数量”:25,“价格”:50}
,有效负载:[PUT]/api/orders/{orderId}/items/{itemId}
{“数量”:25,“价格”:50}
[DELETE]/api/orders/{orderId}/items/{itemId}
[PUT]/api/orders/{orderId}
立即更新订单的项目:
优点:性能,不允许部分成功
缺点:如果用户更新50个项目,删除50个项目,并向订单中添加新的50个项目,在一个请求中(在订单
实体上放置请求),我们将本质上在不同实体上添加、更新、删除50个项目-订单项目
。我担心这是否是好的RESTful
实践
解决方案C:通过更新。。。集合:[PUT]/api/orders/{orderId}/items
和有效负载:
有效负载中的集合将完全替换系统中的集合,包括添加和删除操作
优点:性能,部分成功是不允许的,你不会弄乱父实体
缺点:对集合调用PUT
请求是一种好的做法吗。通常,当您有PUT
时,URI以某种ID结尾(您正在更新一个实体)。在本例中,URI将以“items”结尾。是这样做的吗
解决方案D:另一种解决方案,可能带有补丁
?以前从未这样做过,但也许可以为订单
实体发送补丁
,修补项目集合。在JsonDocument的值中,我会传递新项目的集合,要删除的项目和更新的项目
那么,我的问题是:以下哪种解决方案最适合这种情况?A、 B、C或(如果存在)D?或者其他我没有想到的解决方案?如果您没有很多物品,那么解决方案A完全可以。它不适合您的情况,因为如果您有许多请求,它会使您的api变得健谈 解决方案B一次发送很多信息。它遵循使用完整资源对象进行更新的实践,甚至还有一个http状态代码来表示部分成功。Response对象是一个考虑因素,让消费者知道成功的新URL,并指出失败的URL(如果有)以及原因。要么去,要么去 解决方案C并没有那么安静。您并没有真正地更新任何单个资源,消费者很难理解 解决方案D是B和C的合并。我希望在这里使用它,因为您并没有真正更新完整的对象。您可以使用与B相同的url 扩展超文本传输协议(HTTP)的几个应用程序 需要一个功能来进行部分资源修改。现存的 HTTP PUT方法只允许完全替换文档。 该提案添加了一个新的HTTP方法PATCH,以修改现有的 HTTP资源。 –RFC 5789
看起来解决方案B最适合您的需求,但它让您担心,因为在一个请求中发生了很多事情。如果每个部件(添加/删除项目等)在概念上都是一件事——订单的更新,我并不认为这是一个问题。解决方案B对我来说似乎是最好的解决方案。解决方案B对我来说似乎是最好的解决方案。如果你想,你也可以添加A,但在内部我可能会调用B。你想在一个事务中一次更新所有内容,所以发送50个请求对我来说是错误的。
{
"customerId": 805,
"isVoided": "false",
"items": [
{
"itemId": 112233,
"quantity": 25,
"price": 50
},
{
"itemId": 445566,
"quantity": 20,
"price": 40
}
]
}
[
{
"op": "replace",
"path": "/IsVoided",
"value": true
}
]
{
"customerId": 805,
"isVoided": "false",
"items": [
{
"itemId": 112233,
"quantity": 25,
"price": 50
},
{
"itemId": 445566,
"quantity": 20,
"price": 40
}
]
}
[
{
"itemId": 112233,
"quantity": 25,
"price": 50
},
{
"itemId": 445566,
"quantity": 20,
"price": 40
}
]