gin中间件实现对查询缓存

在实际工作中,有时候需要对提供的api实现数据缓存,缓解数据压力.一般的做饭就是先查询是否有缓存,如果有则用缓存,没有就查询数据库。

但是每个方法都去实现一遍有点累,现考了到在中间件实现。

在中间件根据请求参数和api地址作为缓存key, 如果有缓存key,直接返回,没有则放行,从response中拿结果。

在gin中的response其实是gin.context.writer,为实现这个功能,需要重新writer方法,

代码如下:

type responseWriter struct {
    gin.ResponseWriter
    b *bytes.Buffer // 记录返回的数据
}

// 重写Writer
func (w responseWriter) Write(b []byte) (int, error) {
    w.b.Write(b)
    return w.ResponseWriter.Write(b)
}

创建一个中间件:

func ApiCache() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 只缓存get的请求
        if c.Request.Method != http.MethodGet {
            c.Next()
            return
        }
        requestUri := c.Request.RequestURI
        params := make([]string, 0)
        for _, v := range c.Params {
            params = append(params, fmt.Sprintf("%s:%s", v.Key, v.Value))
        }
        if len(params) > 0 {
            requestUri += "&" + strings.Join(params, "&")
        }
        // 生成缓存key
        cacheKey := utils.SimpleMd5(requestUri)
        htmlFile := filepath.Join("./cache", cacheKey)
        if utils.FileIsExisted(htmlFile) {
            c.File(htmlFile)
            c.AbortWithStatus(http.StatusOK) // 一定要abort,不然还会继续执行next()
            return
        }

        // 使用重写的writer
        writer := responseWriter{
            c.Writer,
            bytes.NewBuffer([]byte{}),
        }
        c.Writer = writer
        c.Next()

        // 保存缓存
        if c.Writer.Status() == http.StatusOK {
            utils.WriteFile2(htmlFile, writer.b.Bytes())
        }
    }
}

最后就能实现根据api缓存了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值