.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 ...
随机推荐
- python在linux中import cv2问题
python中import cv2遇到的错误及安装方法标签 1 错误: ImportError: libXext.so.6: cannot open shared object file: No su ...
- angular 8 配置路由
一.生成路由文件 按照惯例,有一个独立模块来配置相关路由,这个模块类的名字叫做AppRoutingModule,位于src/app下的app-routing.module.ts文件中. 使用CLI生成 ...
- 关于近期使用webpack所引发的思考
近期,(使其也挺长时间了).使用了一段时间的webpack. 但是在使用期间个人感觉并不想网上说的那样好,个人对webpack的评价并不是很高,甚至有点反感使用webpack. 个人感觉使用webpa ...
- laravel——表操作集成操作
背景:通过判断不同的请求参数,返回不同的需要的数据 一.准备工作: 数据库新建一个表 DROP TABLE IF EXISTS `tb_category2`; CREATE TABLE IF NOT ...
- Failed to close the ServletOutputStream connection cleanly, Broken pipe
Problem1: 服务端报错:Broken pipejava.io.IOException: Connection timed out at sun.nio.ch.FileDispatcherImp ...
- Luogu-P1450 [HAOI2008]硬币购物-完全背包+容斥定理
Luogu-P1450 [HAOI2008]硬币购物-完全背包+容斥定理 [Problem Description] 略 [Solution] 上述题目等价于:有\(4\)种物品,每种物品有\(d_i ...
- java连接mysql数据库时的时区设置问题(time_zone)
java在连接mysql数据库时,会由于时区设置不正确导致报以下的错误: The server time zone value '???ú±ê×??±??' is unrecognized or ...
- django-ContentType的简单使用
ContentType 一般我们有多张表同时外键关联同一张表的时候,可以考虑使用ContentType models.py from django.db import models from djan ...
- SQL 必知必会笔记--完整介绍sql技巧
PS:完整介绍数据处理,表结构操作,视图,事务处理,存储过程,约束,索引,游标,触发,数据库安全等sql技巧 目录 数据处理 增:插入数据+复制表 删:删除行数据+删除指定列数据 改:更新数据 查:基 ...
- 《少年先疯队》第八次团队作业:Alpha冲刺第五天
前言 第五天冲刺会议 时间:2019.6.18 地点:宿舍 5.1 今日完成任务情况以及遇到的问题. 5.1.1今日完成任务情况 姚玉婷:会员查询消费记录功能的实现 马丽莎:昨天 ...