一键搞定ASP.NET Core Web API幂等性

API的幂等性(Idempotent),是指调用某个方法1次或N次对资源产生的影响结果都是相同的。

GET请求默认是幂等的,因为它只是查询资源,而不会修改资源。

而POST请求默认是不幂等的,多次调用POST方法可能会产生不同的结果,并会创建多个资源。

想象一下,你在扫码支付时,输入金额后点击了2次“确定”按钮,肯定不希望扣2次款。

幂等性保证了操作只会执行一次。

1.思路

使用ASP.NET Core过滤器来处理POST请求,检查请求头中的幂等键(IdempotencyKey)

如果在缓存中未检查到IdempotencyKey,则真实执行操作并缓存响应数据,否则直接返回缓存的响应数据。

这样,操作只能对资源产生一次影响。

原理示意图如下:

2.实现

2.1 IdempotentAttributeFilter

创建自定义Filter。

使用OnActionExecuting方法在执行操作前检查缓存,如有缓存直接返回context.Result;使用OnResultExecuted方法在执行操作后缓存响应。

代码如下:

public class IdempotentAttributeFilter : IActionFilter, IResultFilter
{private readonly IDistributedCache _distributedCache;private bool _isIdempotencyCache= false;const string IdempotencyKeyHeaderName = "IdempotencyKey";private string _idempotencyKey;public IdempotentAttributeFilter(IDistributedCache distributedCache){_distributedCache = distributedCache;}public void OnActionExecuting(ActionExecutingContext context){Microsoft.Extensions.Primitives.StringValues idempotencyKeys;context.HttpContext.Request.Headers.TryGetValue(IdempotencyKeyHeaderName, out idempotencyKeys);_idempotencyKey = idempotencyKeys.ToString();var cacheData = _distributedCache.GetString(GetDistributedCacheKey());if (cacheData != null){context.Result = JsonConvert.DeserializeObject<ObjectResult>(cacheData);_isIdempotencyCache = true;return;}}public void OnResultExecuted(ResultExecutedContext context){//已缓存if (_isIdempotencyCache){return;}var contextResult = context.Result;DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions();cacheOptions.AbsoluteExpirationRelativeToNow = new TimeSpan(24, 0, 0);//缓存:_distributedCache.SetString(GetDistributedCacheKey(), JsonConvert.SerializeObject(contextResult), cacheOptions);}public void OnActionExecuted(ActionExecutedContext context){}public void OnResultExecuting(ResultExecutingContext context){}private string GetDistributedCacheKey(){return "Idempotency:" + _idempotencyKey;}
}

2.2 IdempotentAttribute

创建自定义Attribute。

声明了IdempotentAttribute的Class或者Method,在运行时会创建IdempotentAttributeFilter

代码如下:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class IdempotentAttribute : Attribute, IFilterFactory
{public bool IsReusable => false;public IFilterMetadata CreateInstance(IServiceProvider serviceProvider){var distributedCache = (IDistributedCache)serviceProvider.GetService(typeof(IDistributedCache));var filter = new IdempotentAttributeFilter(distributedCache);return filter;}
}

3.使用

3.1 创建项目

新建ASP.NET Core Web API项目,实现代码如下:

private static List<WeatherForecast> _db = new List<WeatherForecast>();[HttpPost]
public WeatherForecast Post(int temperature)
{var data = new WeatherForecast { TemperatureC = temperature };_db.Add(data);return data;
}[HttpGet]
public IEnumerable<WeatherForecast> Get()
{return _db.Select(p => new WeatherForecast{TemperatureC = p.TemperatureC,Summary = Summaries[rng.Next(Summaries.Length)]}).ToArray();
}

这里用一个静态变量模拟数据库,POST请求写入数据,GET请求读取数据。

3.2 设置幂等

为Post方法加上Idempotent Attribute:

[Idempotent]
public WeatherForecast Post(int temperature)

3.3 注册分布式缓存

从上面的原理图我们可以看到,必须增加分布式缓存,用于保存幂等键的值和响应数据。

修改Startup.cs:

public void ConfigureServices(IServiceCollection services)
{...services.AddDistributedMemoryCache();
}

3.4 测试

运行Web API,使用不同IdempotencyKey执行POST请求,然后获取数据:

可以看到,同一IdempotencyKey执行了2次,但是只写入了一条数据,成功!

结论

为了确保关键Web API的高可用性和业务连续性,实现幂等性是重要的一步。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300177.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你这么爱听歌,一定活得很难过吧 | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅让笑声飞沙雕营长大象ROV全球第一最搞搞笑热门神吐槽朱莉生活日记

暴笑小笑话集----转自通信公社

07-4-11.女&#xff1a;“只要有钱&#xff0c;我嫁给谁都行。”男&#xff1a;“银行的保险柜你嫁吗&#xff1f;” 2.争吵的时候&#xff0c;男人和女人的区别就像是和机关枪的区别。3.我妻子想减肥&#xff0c;所以她每天都去骑马。结果马一个月之中瘦了四十斤。4.病人&…

Web开发中的矢量绘图(vml,svg)处理和应用

为什么80%的码农都做不了架构师&#xff1f;>>> 前言 1991 年物理学家 Tim Berners-Lee 首次在因特网上发布了 HTML 的第一版描述规范文档。经过了 20 多年的发展&#xff0c;HTML 语言成为如今编程最为广泛的语言和互联网上采用最广的文档格式。虽然 HTML 发展十分…

c语言环境窗口组成,如何搭建C语言环境

如何搭建C语言环境开发C程序的时候我们用的开发软件有VC6.0、visual studio等等&#xff0c;但对于有些简单的程序我们更喜欢用记事本或者notepad等方便的工具进行编辑&#xff0c;编辑完后再通过cmd窗口编译运行&#xff0c;但我们得给它一个环境&#xff0c;以便它可以是使用…

C#新手该如何规划学习【学习路线指南】

花费了几天时间整理了C#学习路线图&#xff0c;可以说是纯野生C#程序员成长路线规划&#xff0c;在这里分享下&#xff0c;希望可以帮助到想从事C#开发的同学们。本人阅历尚浅&#xff0c;有些知识点可能分享不正确&#xff0c;希望广大网友评论区补充&#xff0c;我会同步修正…

msdn中C#中常用词汇概念(转帖)

p C# 是一种简洁、类型安全的面向对象的语言&#xff0c;开发人员可以使用它来构建在 .NET Framework 上运行的各种安全、可靠的应用程序。 p C# 作为一种面向对象的语言,支持封装、继承和多态性概念。所有的变量和方法&#xff0c;包括 Main 方法&#xff08;应用程…

丰巢刷脸取件被小学生破解,号称3D、深度学习加持的人脸识别究竟靠谱吗?...

全世界只有3.14 % 的人关注了青少年数学之旅经费不够&#xff0c;2D来凑&#xff1f;前些天&#xff0c;丰巢智能快递柜被“小学生”用打印照片破解&#xff0c;让人大跌眼镜。据《人民日报》报道&#xff0c;嘉兴上外秀洲外国语学校402班科学小队向都市快报《好奇实验室》报料…

Linux脚本利器sed

sed文本例子使用以下文件 $pg quote.txt The honeysuckle band played all night long for only $90. It was an evening of splendid music and company. Too bad the disco floor fell through at 23:10. The local nurse Miss P.Neave was in attendance.1 sed怎样读取…

伍迷随想冷饭集 之 瞻前顾后之随想

哈哈&#xff0c;很是开心&#xff0c;今天是我的生日&#xff0c;由于各地对年龄的计算方法不同&#xff0c;你认为我是25周岁、26岁、还是27虚岁都行&#xff0c;反正是又老一年了。几乎在每年的这个时候&#xff0c;我都会对自己做一个小小的总结&#xff0c;不过以前都没有…

c语言while运行出现错误,【图片】为什么我的while(1)不执行啊?【c语言吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include #include #include /*设定&#xff1a;玩家&#xff1a;攻击力&#xff0c;生命值&#xff0c;技能效果&#xff0c;CD&#xff1b;敌人&#xff1a;攻击力&#xff0c;生命值&#xff0c;CD&#xff1…

研究生和本科生

一个月拼死拼活&#xff0c;一分钱不花才能买到连半个单人床都不到的屁大点地方。结婚得10年&#xff0c;买房得25年……这样生活还不如花5块钱买把犏刀抢银行&#xff01;&#xff01;&#xff01;于是我做梦手持菜刀&#xff0c;凶神恶刹一样冲到银行门口。突然&#xff0c;一…

微软面向初学者的机器学习课程:3.1-构建使用ML模型的Web应用程序

写在前面&#xff1a;最近在参与microsoft/ML-For-Beginners的翻译活动&#xff0c;欢迎有兴趣的朋友加入&#xff08;https://github.com/microsoft/ML-For-Beginners/issues/71&#xff09;构建使用ML模型的Web应用程序在本课中&#xff0c;你将在一个数据集上训练一个ML模型…

我们单位里新来的应届毕业生(转贴)

我在一个BBS上看到的贴,觉得很好玩,就转过来了....大家一起分享吧....1.公司新配给我一个助理.今天,我,助理以及我们老总,去局里开会.会毕,领导要写个注意事项给我们.我和老总当时拿笔都不太方便.我随口问助理..你带笔了吗?他马上回答:带了然后,几双眼睛看着他..接下来的十秒钟…

boost pool内存池库使用简要介绍

2019独角兽企业重金招聘Python工程师标准>>> 我厂内存次神马的一般都自己实现。我曾经也自己写过一个demo(mempool)。后来发现boost库里面有一个内存池库boost pool&#xff0c;貌似很好用&#xff0c;使用挺好&#xff0c;例子可以贴出来。 boost一共有4种内存池&…

嫁给我好吗?| 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅

c语言得到txt文件的长度,我利用C语言实现SHA-256算法,需要从一个txt文件中读出数据并把...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼并把得到的密文写入另一个txt文件张该怎么改代码啊&#xff1f;#include #include extern char* StrSHA256(const char* str, long long length, char* sha256);int main(void){char text[] "123";char sha256[65];StrS…

惠普前总裁孙振耀指点职业规划

HP大中华区总裁孙振耀退休感言&#xff1a;如果这篇文章没有分享给你&#xff0c;那是我的错。 如果这篇文章分享给你了&#xff0c;你却没有读&#xff0c;继续走弯路的你不要怪我。 如果你看了这篇文章&#xff0c;只读了一半你就说没时间了&#xff0c;说明你已经是个“茫”…

.NET Core etcd 配置源

etcd 是一个高可用的 Key/Value 存储系统&#xff0c;主要用于共享配置和服务发现&#xff0c;和目前比较主流的配置中心&#xff08;如&#xff1a;Spring Cloud Config、Apollo、Consul、Nacos&#xff09;、注册中心&#xff08;如&#xff1a;Zookeeper、Eureka、Consul、N…

继相对论、量子论之后,它的出现,给牛顿又来了致命一刀

全世界只有3.14 % 的人关注了青少年数学之旅前两天&#xff0c;有模友留言。今天&#xff0c;它来了。“微小的变化能带动整个系统的长期的巨大的连锁反应。”——节选自其实“混沌”一词&#xff0c;最早指的是宇宙未形成之前的混乱状态。/此混沌非彼馄饨/在希腊神话中&#x…

django基础1--django安装与helloworld测试

第一步测试服务器是否安装python直接输入python命令即可&#xff0c;ctrld退出第二步上传django安装包&#xff0c;解压进入后python setup.py install 安装第三步Python导入django看看是否生效先python进入python环境&#xff0c;然后import django命令查看是否正常执行第四步…