PATCH请求REST API之MyDeltas.net
PATCH是REST API支持的请求之一。
REST API的请求常见的是GET和POST,其中PUT、DELETE和PATCH也很重要。
PATCH表示部分更新,用POST当然可以代替,PATCH语义更好更准确。
1. JSON Patch是一种实现PATCH的方案
2. ODATA也支持Patch
ODATA包含Delta功能,比JSON Patch简洁
但是Delta只能用于ODataController
3. MyDeltas.net是本人参看ODATA的Delta功能实现的一个小工具
4. MyDeltas和JSON Patch对比
|
|
|
以上是使用NodeBook实现的对比,大家可以从本项目源码中下载用vscode打开测试
gitbub地址: https://github.com/donetsoftwork/MyDelta.net/tree/master/Notes
或gitee地址: https://gitee.com/donetsoftwork/MyDelta.net/tree/master/Notes
以上很明显MyDeltas生成的json比JSON Patch的简洁。
以前很多项目对同一个实体有很多修改方法,改头像、改昵称、改生日、改性别等等,太多了。
用Patch都可以合并,这样就简洁明了。
JSON Patch更适合复杂对象,它支持Add、Remove、Replace等,MyDeltas相当于JSON Patch的Replace
如果我们做微服务的API,实体类简单直接用MyDeltas就好了
这里说的实体类简单并不是说支持的字段少,而是尽量不要一个实体类又包含多个其他实体类的对象
比如Post和Comment,如果Post含Comment列表,用JSON Patch才好处理
如果把Post和Comment拆分两个API,JSON Patch的Add、Remove能用上的机会就不多了
5. MyDeltas功能
5.1 通过nuget安装MyDeltas
dotnet add package MyDeltas --version 0.3.0-alpha
5.2 MyDelta通过IMyDeltaFactory工具来构造
IMyDeltaFactory factory = new MyDeltaFactory();
MyDelta<TodoItem> delta = factory.Create<TodoItem>();
5.3 MyDelta支持System.Text.Json序列化和反序列化
IMyDeltaFactory factory = new MyDeltaFactory();
MyDelta<TodoItem> delta = factory.Create<TodoItem>();
delta.TrySetValue("Name", "Test");
string json = JsonSerializer.Serialize(delta);
//{"Name":"Test"}
var json = "{\"Name\":\"Test\"}";
MyDelta<TodoItem>? delta = JsonSerializer.Deserialize<MyDelta<TodoItem>>(json);
其中反序列化也是调用IMyDeltaFactory来构造MyDelta
5.4 Patch和Put功能都是把MyDelta数据应用到实例对象上
Patch只应用变更的部分,并返回是否变更成功
Put是把变化部分和没变化部分都复制过去
/// <summary>
/// 增量修改
/// </summary>
/// <param name="original"></param>
/// <returns>是否变化</returns>
public bool Patch(TStructuralType original)
{
bool changed = false;
foreach (var item in _data)
{
if (_members.TryGetValue(item.Key, out var member))
changed = member.TrySetValue(original, item.Value);
}
return changed;
}
/// <summary>
/// 覆盖
/// </summary>
/// <param name="original"></param>
/// <returns></returns>
public void Put(TStructuralType original)
{
foreach (var item in _members)
{
if (_data.TryGetValue(item.Key, out var value))
item.Value.SetValue(original, value);
else
item.Value.Copy(_instance, original);
}
}
6. MyDeltas性能问题
MyDelta通过IMyDeltaFactory来操作实体类的属性或字段,默认实现MyDeltaFactory是基于反射的PropertyInfo和FieldInfo
虽然.net9的反射性能已经提高很多了,但与手写代码还是有点差距,为此MyDeltas提供了扩展方案
6.1 DelegateBuilder手写代码扩展
DelegateBuilder可以直接构造MyDelta也可以扩展IMyDeltaFactory
var builder = new DelegateBuilder<TodoItem>()
.Add(nameof(TodoItem.Id), obj => obj.Id, (obj, value) => obj.Id = value)
.Add(nameof(TodoItem.Name), obj => obj.Name, (obj, value) => obj.Name = value)
.Add(nameof(TodoItem.IsComplete), obj => obj.IsComplete, (obj, value) => obj.IsComplete = value)
.Add(nameof(TodoItem.Remark), obj => obj.Remark, (obj, value) => obj.Remark = value);
TodoItem todo = new() { Id = 1, Name = "Test1" };
var myDelta = _builder.Create(todo);
myDelta.TrySetValue(nameof(TodoItem.Name), "todo1");
DelegateBuilder没定义的IMyDeltaFactory会补足
var builder = new DelegateBuilder<TodoItem>()
.Add(nameof(TodoItem.Id), obj => obj.Id, (obj, value) => obj.Id = value)
.Add(nameof(TodoItem.Name), obj => obj.Name, (obj, value) => obj.Name = value);
MyDeltaFactory factory = new MyDeltaFactory()
.Use(builder.Members);
MyDelta<TodoItem> delta = factory.Create<TodoItem>();
7. 如果嫌弃手写代码太繁琐可以使用MyDeltas.Emit
7.1 通过nuget安装MyDeltas.Emit
dotnet add package MyDeltas.Emit --version 0.3.0-alpha
7.2 使用EmitDeltaFactory代替MyDeltaFactory
IMyDeltaFactory emitFactory = new EmitDeltaFactory();
7.3 配置Json序列化
string json = JsonSerializer.Serialize(delta, new JsonSerializerOptions
{
Converters =
{
new MyDeltaConverterFactory(new MyDeltaFactory())
}
});
IMyDeltaFactory deltaFactory = new EmitDeltaFactory();
services.AddSingleton(deltaFactory)
.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new MyDeltaConverterFactory(deltaFactory));
});
源码托管地址: https://github.com/donetsoftwork/MyDeltas.net ,也欢迎大家直接查看源码。
gitee同步更新:https://gitee.com/donetsoftwork/MyDeltas.net
文档地址: https://donetsoftwork.github.io/MyDelta.net/index.html
如果大家喜欢请动动您发财的小手手帮忙点一下Star。
PATCH请求REST API之MyDeltas.net的更多相关文章
- [译] 在Web API 2 中实现带JSON的Patch请求
原文链接:The Patch Verb in Web API 2 with JSON 我想在.NET4.6 Web API 2 项目中使用Patch更新一个大对象中的某个字断,这才意识到我以前都没有用 ...
- patch请求--501错误
通过命令 tail -f /var/log/wildfly/wrapper.log -n 1000 查看控制台: 并没有报红. 未显示具体哪行代码有错误. debug运行patch请求,根本没有进入p ...
- 在ASP.NET Core中用HttpClient(三)——发送HTTP PATCH请求
在前面的两篇文章中,我们讨论了很多关于使用HttpClient进行CRUD操作的基础知识.如果你已经读过它们,你就知道如何使用HttpClient从API中获取数据,并使用HttpClient发送PO ...
- 使用 HttpClient 请求 Web Api
1.获取 post 请求 body 内容 [HttpPost] public string GetId() { //如果方法参数里面有 [FromBody],则需要重新调整内容指针,再进行读取. // ...
- patch 请求时,关于id的报错问题
在更新操作时,先显示要更新的数据内容,再修改 在发送patch请求时出现 After applying the update to the document {_id: ObjectId('55be3 ...
- Spring Data REST PATCH请求 远程代码执行漏洞案例(CVE-2017-8046)
恶意的PATCH请求使用精心构造的JSON数据提交到spring-data-rest服务可以执行任意JAVA代码 1. 背景 Spring Data REST是Spring Data项目的一部分,可以 ...
- vue中Axios请求豆瓣API数据并展示到Swipe中
vue中Axios请求豆瓣API数据并展示到Swipe中 1.首先是安装Axios: 安装方法cnpm install axios --save 等待npm安装完毕: 2.在main.js中引入axi ...
- Spring Data REST PATCH请求远程代码执行漏洞(CVE-2017-8046) 本地复现方法
#1背景 Spring Data REST是Spring Data项目的一部分,可以轻松地在Spring Data存储库之上构建超媒体驱动的REST Web服务. 恶意的PATCH请求使用精心构造 ...
- .Net Core使用HttpClient请求Web API注意事项
HttpClient 使用HttpClient可以很方便的请求Web API,但在使用时有一些需要注意的地方,不然会给你的程序带来毁灭性的问题. HttpClient是一个继承了IDisposable ...
- 腾讯云图片鉴黄集成到C# SQL Server 怎么在分页获取数据的同时获取到总记录数 sqlserver 操作数据表语句模板 .NET MVC后台发送post请求 百度api查询多个地址的经纬度的问题 try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后? js获取某个日期
腾讯云图片鉴黄集成到C# 官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: public c ...
随机推荐
- 一文彻底搞懂 MCP:AI 大模型的标准化工具箱
MCP 最近在 AI 领域 引发了 广泛关注,特别是在 海外各大社区 中,大家热烈讨论,热度 相当高. 我打开了 Google Trends,这是一个专门用于查看全球热点趋势的网站. 输入关键词后,可 ...
- TCP连接(Netty)
启动类增加 public static void main(String[] args) { SpringApplication application = new SpringApplication ...
- base的含义及使用及与this的区别
C#中base关键字的几种用法 - bobob - 博客园 (cnblogs.com) C#构造函数里的base和this的区别 - 傲世狂枫 - 博客园 (cnblogs.com) 我的理解 1.在 ...
- Spring基于xml的CRUD
目录 基于xml的CRUD 代码实现 测试 基于xml的CRUD 源码 使用C3P0连接池 使用dbutils包中的QueryRunner类来对数据库进行操作 代码实现 pom.xml <?xm ...
- 【记录】smartctl|Linux如何通过smartctl查看有没有坏的磁盘?以及使用时长、电源周期、故障记录等
smartctl是一个用于监测和分析硬盘健康状态的工具,可以用于检测是否存在坏的磁盘.以下是使用smartctl检查磁盘健康状态的步骤: 安装smartctl软件 在Linux系统中,smartc ...
- 【记录】Python3|用百度语音 API 朗读你的小说TXT
百度语音合成官方教程_AI开放平台 百度语音合成官方demo_github.com 简单地写了一个按段落朗读文本的demo:DEMO链接_gitee.com. 有时候会请求不到数据,不知道是网络原因还 ...
- 【BUG】Message = “无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。“, StackTrace = “ 在 System.Reflection.
环境: Visual Studio 2019 C#项目遇到这种情况时,是因为有多个依赖出了问题(也可能是只有一个但被误报成多个),此时点开"查看详细信息",可以快速监视Except ...
- C++11——右值引用&完美转发
总而言之,右值引用,完美转发,std::move()都是为了在程序运行过程中,避免变量多次重复的申请和释放内存空间,使用移动语义将申请的空间通过这几种方式进行循环使用,避免重新开辟新空间和拷贝浪费算力 ...
- MongoDB创建数据库文件的存放位置
为什么要写这篇呢,故事还得从MongoDB如下所示的罢工说起 怎么就拒绝访问了呢???? 在执行mongod命令可发现如下问题: 于是,在蜘蛛网上到处扒拉,以解它这不解之症,也解我燃眉之急 终于... ...
- C#快速排序算法实现及循环条件细节思考
C#快速排序算法实现及循环条件细节思考 快速排序是一种分治思想的递归排序算法,其基本思想为: 在每一步中,挑选一个主元(pivot)出来,比如第一个元素 然后遍历除主元外的剩下的元素,把所有小于主元的 ...

