简体   繁体   English

如何在 WebApi Core 中设计多个补丁请求

[英]How to design Multiple Patch requests in WebApi Core

I would like to know what's the best way to design multiple updates to the resource(s) in WebApi .Net Core.我想知道在 WebApi .Net Core 中设计多个资源更新的最佳方法是什么。

For example, I would like to enable the following features for users resources例如,我想为users资源启用以下功能

  • Update User Password更新用户密码
  • Update User role更新用户角色
  • Update User Details (such as Firstname, last name, etc.)更新用户详细信息(例如名字、姓氏等)

So, according to REST tutorials and articles, I learnt that I need to use PATCH method to update partial resource.所以,根据 REST 教程和文章,我了解到我需要使用PATCH方法来更新部分资源。

We did some discussions in the team and we are confused with these two options:我们在团队中进行了一些讨论,我们对这两个选项感到困惑:

Option 1选项1

implement multiple PATCH routes for different actions为不同的动作实现多个 PATCH 路由

  • PATCH /api/users/{id}/password补丁/api/users/{id}/password
  • PATCH /api/users/{id}/role补丁/api/users/{id}/role
  • PATCH /api/users/{id}/details补丁/api/users/{id}/details

Option 2选项 2

implement ONLY single PATCH action for the whole resource.对整个资源实施 ONLY 单个 PATCH 操作。 Users will send application/json-patch+json for partial updates.用户将发送 application/json-patch+json 进行部分更新。

  • PATCH /api/users/id (accepts JsonPatchDocument parameter) PATCH /api/users/id (接受JsonPatchDocument参数)

I tried to find the best practices for Restful Route Namings and most of them only cover for simple CRUD activities or nested resources.我试图找到 Restful Route Namings 的最佳实践,其中大部分仅涵盖简单的 CRUD 活动或嵌套资源。

For this kind of multiple UPDATE operations, may I know what's the best practice for naming the routes?对于这种多个 UPDATE 操作,我可以知道命名路由的最佳做法是什么吗? Or the term for it to study in-depth?或者它的深入研究的术语? Thanks.谢谢。

PATCH requests are used to update parts of single resources, ie where only a specific subset of resource fields should be replaced. PATCH请求用于更新单个资源的部分,即只应替换资源字段的特定子集。 The semantic is best described as "please change the resource identified by the URL according to my change request".语义最好地描述为“请根据我的更改请求更改由 URL 标识的资源”。

  • PATCH requests are usually applied to single resources as patching entire collection is challenging PATCH请求通常应用于单个资源,因为修补整个集合具有挑战性
  • PATCH requests are usually not robust against non-existence of resource instances PATCH请求对于不存在的资源实例通常不稳健
  • on successful PATCH requests, the server will update parts of the resource addressed by the URL as defined by the change request in the payload在成功的PATCH请求中,服务器将更新由负载中的更改请求定义的 URL 寻址的部分资源
  • successful PATCH requests will usually generate 200 or 204 (if resources have been updated with or without updated content returned)成功的PATCH请求通常会生成200204 (如果资源已更新并返回更新内容)

Note : since implementing PATCH correctly is a bit tricky, I strongly suggest to choose one and only one of the following patterns per endpoint.In preference order:注意:由于正确实现PATCH有点棘手,我强烈建议每个端点选择以下模式中的一种且仅一种。按优先顺序:

  1. use PUT with complete objects to update a resource as long as feasible (ie do not use PATCH at all).只要可行,就使用带有完整对象的PUT来更新资源(即根本不使用PATCH )。
  2. use PATCH with partial objects to only update parts of a resource, whenever possible.只要有可能,将PATCH与部分对象一起使用以仅更新资源的一部分。 (This is basically JSON Merge Patch , a specialized media type application/merge-patch+json that is a partial resource representation.) (这基本上是JSON Merge Patch ,一种专门的媒体类型application/merge-patch+json ,它是部分资源表示。)
  3. use PATCH with JSON Patch , a specialized media type application/json-patch+json that includes instructions on how to change the resource.PATCHJSON Patch一起使用,这是一种专门的媒体类型application/json-patch+json ,其中包含有关如何更改资源的说明。
  4. use POST (with a proper description of what is happening) instead of PATCH , if the request does not modify the resource in a way defined by the semantics of the media type.如果请求没有以媒体类型语义定义的方式修改资源,则使用POST (对正在发生的事情进行适当的描述)而不是PATCH

Option 1 seems like bad design, because you will have a lot of endpoints for each property.选项 1似乎是糟糕的设计,因为每个属性都有很多端点。

Option 2 is following by REST recommendation and specified in RFC 6902选项 2遵循 REST 建议并在RFC 6902 中指定

You can implement it in following ways:您可以通过以下方式实现它:

  • Delta (part of Microsoft ASP.NET WebAPI OData): it has some problems with numbers when using JSON. Delta (Microsoft ASP.NET WebAPI OData 的一部分):在使用 JSON 时存在一些数字问题。 You also need to install the package with all its non-trivial dependencies;您还需要安装包及其所有重要的依赖项;
  • JSON Patch : the client must organize the data per operation and the size of the request is not optimized. JSON Patch :客户端必须组织每个操作的数据,并且请求的大小没有优化。
  • Use Simple.HttpPatch that allows to easily apply partial updates使用Simple.HttpPatch可以轻松应用部分更新
  • One more SimplePatch implementation另一个SimplePatch实现

Route Namings路由命名

  • use plural nouns for resource name.资源名称使用复数名词。 Do not mix up singular and plural nouns.不要混淆单数和复数名词。 Keep it simple and use only plural nouns for all resources( users , instead of user )保持简单,所有资源只使用复数名词( users ,而不是user

  • if you have two base URLs per resource then the first URL is for a collection (list);如果每个资源有两个基本 URL,则第一个 URL 用于集合(列表); the second is for a specific element in the collection ( /users and /users/1 )第二个用于集合中的特定元素( /users/users/1

  • if you have relations, use sub-resources for it如果您有关系,请为其使用子资源

/users/1/phones - returns a list of phones for user 1 /users/1/phones - 返回用户 1 的电话列表
/users/1/phones/1 - returns phone #1 for user 1 /users/1/phones/1 - 为用户 1 返回电话 #1

  • keep verbs out of your base URLs.将动词排除在基本 URL 之外。 Use HTTP request methods GET , POST , PUT/PATCH , DELETE with two base URLs to CRUD operations.使用 HTTP 请求方法GETPOSTPUT/PATCHDELETE和两个基本 URL 进行 CRUD 操作。 The point is that developers probably don't need the documentations to understand how the API behaves.In other way you will have a long list of URLs and no consistent pattern making it difficult for developers to learn how to use your API关键是开发人员可能不需要文档来了解 API 的行为方式。否则,您将拥有一长串 URL 并且没有一致的模式,这使开发人员难以学习如何使用您的 API

  • complex things need to be hidden behind the ?复杂的东西需要隐藏在背后? . . Almost every API has a lot of parameters that you can read, update, filter and work with them in any other ways.几乎每个 API 都有许多参数,您可以以任何其他方式读取、更新、过滤和使用它们。 But all these parameters should not be visible in the base addresses.但是所有这些参数都不应该在基地址中可见。 It is best to specify the parameters within the reference to the base addresses.最好在对基地址的引用中指定参数。

GET /users/1234?firstName=Bill&PhoneNumber="1111" GET /users/1234?firstName=Bill&PhoneNumber="1111"

Also see links另见链接

Use PUT with json of whole object and just change only what is necessary将 PUT 与整个对象的 json 一起使用,只更改必要的内容

something like (use try-catch ofc)类似(使用 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);
}

In that JSON u mustnt have all atributes.. just those who u want to change... cause:在那个 JSON 中,你不能拥有所有属性......只有你想要改变的那些......原因:

UrObject.someValue = value.newValue.hasValue ? value : UrObject.someValue;

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

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