内容简介:以前给API接口写缓存基本都是这样写代码:然后把这一坨坨代码都散落在每个地方。某一天,突然想起我这边的缓存基本时间都差不多,而且都是给Web API用的,
.NET Core教程--给API加一个服务端缓存啦
以前给API接口写缓存基本都是这样写代码:
// redis key var bookRedisKey = ConstRedisKey.RecommendationBooks.CopyOne(bookId); // 获取缓存数据 var cacheBookIds = _redisService.ReadCache<List<string>>(bookRedisKey); if (cacheBookIds != null) { // return } else { // 执行另外的逻辑获取数据, 然后写入缓存 }
然后把这一坨坨代码都散落在每个地方。
某一天,突然想起我这边的缓存基本时间都差不多,而且都是给Web API用的,
直接在API层支持缓存不就完事了。
所以, 这里用什么来做呢。
在.NET Core Web API这里的话, 两种思路:Middleware 或者ActionFilter.
不了解的同学可以看下面的文档:
ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器
ASP.NET Core 中文文档 第三章 原理(2)中间件
基于我这边只是部分接口支持缓存的话, 直接还是用ActionFilter实现就可以.
没撒说的, 直接上代码.
using System; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Newtonsoft.Json.Linq; namespace XXXAPI.Filters { public class DefaultCacheFilterAttribute : ActionFilterAttribute { // 这个时间用于给子类重写,实现不同时间级别的缓存 protected TimeSpan _expireTime; // redis读写的类,没撒看的 private readonly RedisService _redisService; public DefaultCacheFilterAttribute(RedisService redisService) { _redisService = redisService; } public override void OnActionExecuting(ActionExecutingContext context) { if (context.HttpContext.Request.Query.ContainsKey("refresh")) { return; } KeyConfig redisKey = GetRequestRedisKey(context.HttpContext); var redisCache = _redisService.ReadCache<JToken>(redisKey); if (redisCache != null) { context.Result = new ObjectResult(redisCache); } return; } public override void OnActionExecuted(ActionExecutedContext context) { KeyConfig redisKey = GetRequestRedisKey(context.HttpContext); var objResult = (ObjectResult)context.Result; if (objResult == null) { return; } var jToken = JToken.FromObject(objResult.Value); _redisService.WriteCache(redisKey, jToken); } private KeyConfig GetRequestRedisKey(HttpContext httpContext) { var requestPath = httpContext.Request.Path.Value; if (!string.IsNullOrEmpty(httpContext.Request.QueryString.Value)) { requestPath = requestPath + httpContext.Request.QueryString.Value; } if (httpContext.Request.Query.ContainsKey("refresh")) { if (httpContext.Request.Query.Count == 1) { requestPath = requestPath.Replace("?refresh=true", ""); } else { requestPath = requestPath.Replace("refresh=true", ""); } } // 这里也就一个redis key的类 var redisKey = ConstRedisKey.HTTPRequest.CopyOne(requestPath); if (_expireTime != default(TimeSpan)) { redisKey.ExpireTime = _expireTime; } return redisKey; } } public static class ConstRedisKey { public readonly static KeyConfig HTTPRequest = new KeyConfig() { Key = "lemon_req_", ExpireTime = new TimeSpan(TimeSpan.TicksPerMinute * 30), DBName = 5 }; } public class KeyConfig { public string Key { get; set; } public TimeSpan ExpireTime { get; set; } public int DBName { get; set; } public KeyConfig CopyOne(string state) { var one = new KeyConfig(); one.DBName = this.DBName; one.Key = !string.IsNullOrEmpty(this.Key) ? this.Key + state : state; one.ExpireTime = this.ExpireTime; return one; } } }
然后使用的地方, 直接给Controller的Action方法加上注解即可.
如:
[HttpGet("v1/xxx/latest")] [ServiceFilter(typeof(DefaultCacheFilterAttribute))] public IActionResult GetLatestList([FromQuery] int page = 0, [FromQuery]int pageSize = 30) { return Ok(new { data = _service.LoadLatest(page, pageSize), code = 0 }); }
完事...
哦, 记得在Startup.cs注入 DefaultCacheFilterAttribute.
这个注入就不用我来写的吧.
美中不足的地方在于暂时还不知道怎么直接在注解上面支持自定义缓存时间,
凑合先用了.
完结, 拜.....
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- mybatis教程--查询缓存(一级缓存二级缓存和整合ehcache)
- hibernate教程--一级缓存详解
- hibernate教程--一级缓存详解
- 分布式缓存Redis扫盲教程
- GraphQL 教程(六)—— N+1问题和缓存等问题
- Spring Boot 2.x基础教程:EhCache缓存的使用
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
我知道他想看什么
沙建军 / 中信出版社 / 2018-1 / 48.00
社交媒体迅速发展、信息快速迭代、时间碎片化;大数据、智能终端、物联网横空出世;移动支付、网红经济和传统营销失效,这些都让这个时代的媒体、内容、渠道、产品之间的边界越来越模糊,也从根本上改变了营销的逻辑,内容营销从热词变成趋势,变成营销的底层思维。未来一切都是媒体,形式也是内容。 本书作者通过对国内外36个内容营销的新近案例的故事化描述和透彻分析,提出“组织媒介化”“营销内容化”“内容情趣化”......一起来看看 《我知道他想看什么》 这本书的介绍吧!