繁体   English   中英

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

[英]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 进行部分更新。

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

我试图找到 Restful Route Namings 的最佳实践,其中大部分仅涵盖简单的 CRUD 活动或嵌套资源。

对于这种多个 UPDATE 操作,我可以知道命名路由的最佳做法是什么吗? 或者它的深入研究的术语? 谢谢。

PATCH请求用于更新单个资源的部分,即只应替换资源字段的特定子集。 语义最好地描述为“请根据我的更改请求更改由 URL 标识的资源”。

  • PATCH请求通常应用于单个资源,因为修补整个集合具有挑战性
  • PATCH请求对于不存在的资源实例通常不稳健
  • 在成功的PATCH请求中,服务器将更新由负载中的更改请求定义的 URL 寻址的部分资源
  • 成功的PATCH请求通常会生成200204 (如果资源已更新并返回更新内容)

注意:由于正确实现PATCH有点棘手,我强烈建议每个端点选择以下模式中的一种且仅一种。按优先顺序:

  1. 只要可行,就使用带有完整对象的PUT来更新资源(即根本不使用PATCH )。
  2. 只要有可能,将PATCH与部分对象一起使用以仅更新资源的一部分。 (这基本上是JSON Merge Patch ,一种专门的媒体类型application/merge-patch+json ,它是部分资源表示。)
  3. PATCHJSON Patch一起使用,这是一种专门的媒体类型application/json-patch+json ,其中包含有关如何更改资源的说明。
  4. 如果请求没有以媒体类型语义定义的方式修改资源,则使用POST (对正在发生的事情进行适当的描述)而不是PATCH

选项 1似乎是糟糕的设计,因为每个属性都有很多端点。

选项 2遵循 REST 建议并在RFC 6902 中指定

您可以通过以下方式实现它:

  • Delta (Microsoft ASP.NET WebAPI OData 的一部分):在使用 JSON 时存在一些数字问题。 您还需要安装包及其所有重要的依赖项;
  • JSON Patch :客户端必须组织每个操作的数据,并且请求的大小没有优化。
  • 使用Simple.HttpPatch可以轻松应用部分更新
  • 另一个SimplePatch实现

路由命名

  • 资源名称使用复数名词。 不要混淆单数和复数名词。 保持简单,所有资源只使用复数名词( users ,而不是user

  • 如果每个资源有两个基本 URL,则第一个 URL 用于集合(列表); 第二个用于集合中的特定元素( /users/users/1

  • 如果您有关系,请为其使用子资源

/users/1/phones - 返回用户 1 的电话列表
/users/1/phones/1 - 为用户 1 返回电话 #1

  • 将动词排除在基本 URL 之外。 使用 HTTP 请求方法GETPOSTPUT/PATCHDELETE和两个基本 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.

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