.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.
这个注入就不用我来写的吧.
美中不足的地方在于暂时还不知道怎么直接在注解上面支持自定义缓存时间,
凑合先用了.
完结, 拜.....
.NET Core教程--给API加一个服务端缓存啦的更多相关文章
- 多个微信小程序一个服务端架构
由于某些特定的业务场景,当多个小程序需要一个服务端后台提供数据时,大家可能想到是HTTP路由.是的,实际上我们使用微服务的GateWay网关也是一样的,如下图微服务架构: 网关GateWay的作用在于 ...
- chkconfig-增加一个服务设置服务自启动
参考 http://www.cnblogs.com/panjun-Donet/archive/2010/08/10/1796873.html 如何增加一个服务: 1.服务脚本必须存放在/etc/ini ...
- react+redux教程(六)redux服务端渲染流程
今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...
- ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析
ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...
- 基于 springMVC 的 RESTful HTTP API 实践(服务端)
理解 REST REST(Representational State Transfer),中文翻译叫"表述性状态转移".是 Roy Thomas Fielding 在他2000年 ...
- socket基础实例(一个服务端对应一个客户端情形)
服务端处理1个客户端的例子 运行结果: (1) while(accept+if(recv)) 情形 执行服务端进程: [root@localhost single_link]# ./server [s ...
- 简单服务端缓存API设计
Want 我们希望设计一套缓存API,适应不同的缓存产品,并且基于Spring框架完美集成应用开发. 本文旨在针对缓存产品定义一个轻量级的客户端访问框架,目标支持多种缓存产品,面向接口编程,目前支持简 ...
- java基于socket的网络通信,实现一个服务端多个客户端的群聊,传输文件功能,界面使用Swing
最近在复习java的io流及网络编程.但复习写那些样板程序总是乏味的.便准备写个项目来巩固.想来想去还是聊天项目比较好玩.如果日后完成的比较好自己也可以用(哈哈哈).并且自己后面也要继续巩固java多 ...
- WebService或HTTP服务端接收请求转发消息到另一个服务端-实现思路
1.需求结构(WebService) A客户端<->B服务端<->C服务端 说明: a.在B服务端上面添加配置项(1.是否转发消息到C服务端:2.C服务端IP和端口): b.A ...
随机推荐
- Vue通过WebSocket建立长连接
使用场景: 在项目开发中,后端需要处理一连串的逻辑,或者等待第三方的数据返回来进行处理之后在返回给前端,可能时间会很长,而且前端也不知道后端什么时候能处理好(时间长的话会达到10分钟左右),如果采用普 ...
- React 核心思想之声明式渲染
React 发展很快,概念也多,本文目的在于帮助初学者理清 React 核心概念. React 及 React 生态 React 的核心概念只有 2 点: 声明式渲染(Declarative) 基于组 ...
- JAVA - Windows下JDK默认安装的配置参数
JDK版本1.8 JAVA_HOME C:\Program Files\Java\jdk1.8.0_60 CLASSPATH .;%%JAVA_HOME%%\lib;%%JAVA_HOME%%\lib ...
- Oracle 限制行的子句
12c新特性 限制行的子句允许限制查询返回的行.可以指定偏移量,以及要返回的行数或百分比.您可以使用此子句实现Top-N报告.要获得一致的结果,请指定ORDER_by子句以确保具有确定性的排序顺序. ...
- 反射,内置方法,__str__ __repr__
反射 反射用到的mmp模块 def wahaha():print('wahaha') class QQxing: def __init__(self,name): self.name = name d ...
- CPN tools 帮助文档资料和实例
1.替代变迁 包含有替代变迁的页面叫做父页,当CPN网使用替代变迁的时候,替代变迁所表达的逻辑必须在某一个位置得到实现,实现替代变迁逻辑页面叫做子页或者子网. 将替代变迁相邻的库所叫做槽库所,也即是在 ...
- Linux下 启动tomcat 时候同时日志命令
./startup.sh && tail -f ../logs/catalina.out
- python_并发编程——多进程
from multiprocessing import Process import os def func1(): print('子进程1',os.getpid()) #子进程:获取当前进程的进程号 ...
- 分段三次Hermite插值及其与三次样条的比较
分段三次 Hermite 插值多项式 (PCHIP) 语法 p = pchip(x,y,xq) pp = pchip(x,y) 说明 p = pchip(x,y,xq) 返回与 xq 中的查询点对 ...
- getchar()函数举例
#include<stdio.h>void main(){ char ch; ch=getchar(); printf("%c",ch);}