[英]How to design Multiple Patch requests in WebApi Core
我想知道在 WebApi .Net Core 中设计多个资源更新的最佳方法是什么。
例如,我想为users
资源启用以下功能
所以,根据 REST 教程和文章,我了解到我需要使用PATCH
方法来更新部分资源。
我们在团队中进行了一些讨论,我们对这两个选项感到困惑:
选项1
为不同的动作实现多个 PATCH 路由
/api/users/{id}/password
/api/users/{id}/role
/api/users/{id}/details
选项 2
对整个资源实施 ONLY 单个 PATCH 操作。 用户将发送 application/json-patch+json 进行部分更新。
/api/users/id
(接受JsonPatchDocument
参数)我试图找到 Restful Route Namings 的最佳实践,其中大部分仅涵盖简单的 CRUD 活动或嵌套资源。
对于这种多个 UPDATE 操作,我可以知道命名路由的最佳做法是什么吗? 或者它的深入研究的术语? 谢谢。
PATCH
请求用于更新单个资源的部分,即只应替换资源字段的特定子集。 语义最好地描述为“请根据我的更改请求更改由 URL 标识的资源”。
PATCH
请求通常应用于单个资源,因为修补整个集合具有挑战性PATCH
请求对于不存在的资源实例通常不稳健PATCH
请求中,服务器将更新由负载中的更改请求定义的 URL 寻址的部分资源PATCH
请求通常会生成200
或204
(如果资源已更新并返回更新内容) 注意:由于正确实现PATCH
有点棘手,我强烈建议每个端点选择以下模式中的一种且仅一种。按优先顺序:
PUT
来更新资源(即根本不使用PATCH
)。PATCH
与部分对象一起使用以仅更新资源的一部分。 (这基本上是JSON Merge Patch ,一种专门的媒体类型application/merge-patch+json
,它是部分资源表示。)PATCH
与JSON Patch一起使用,这是一种专门的媒体类型application/json-patch+json
,其中包含有关如何更改资源的说明。POST
(对正在发生的事情进行适当的描述)而不是PATCH
。选项 1似乎是糟糕的设计,因为每个属性都有很多端点。
选项 2遵循 REST 建议并在RFC 6902 中指定
您可以通过以下方式实现它:
路由命名
资源名称使用复数名词。 不要混淆单数和复数名词。 保持简单,所有资源只使用复数名词( users
,而不是user
)
如果每个资源有两个基本 URL,则第一个 URL 用于集合(列表); 第二个用于集合中的特定元素( /users
和/users/1
)
如果您有关系,请为其使用子资源
/users/1/phones - 返回用户 1 的电话列表
/users/1/phones/1 - 为用户 1 返回电话 #1
将动词排除在基本 URL 之外。 使用 HTTP 请求方法GET
、 POST
、 PUT/PATCH
、 DELETE
和两个基本 URL 进行 CRUD 操作。 关键是开发人员可能不需要文档来了解 API 的行为方式。否则,您将拥有一长串 URL 并且没有一致的模式,这使开发人员难以学习如何使用您的 API
复杂的东西需要隐藏在背后?
. 几乎每个 API 都有许多参数,您可以以任何其他方式读取、更新、过滤和使用它们。 但是所有这些参数都不应该在基地址中可见。 最好在对基地址的引用中指定参数。
GET /users/1234?firstName=Bill&PhoneNumber="1111"
另见链接
将 PUT 与整个对象的 json 一起使用,只更改必要的内容
类似(使用 try-catch ofc)
[HttpPut("UpdateUser/{id}")]
public bool UpdateUser(string/int id, [FromBody]UrObject value)
{
var item = UrObjRepo.WHere(w=> w.Key == id).FirstOrDefault();
if (item==null)
{
return false; //not found item to update
}
UrObject.someValue = value.newValue.hasValue ? value : UrObject.someValue;
...
UrObjRepo.update(UrObject);
}
在那个 JSON 中,你不能拥有所有属性......只有你想要改变的那些......原因:
UrObject.someValue = value.newValue.hasValue ? value : UrObject.someValue;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.