Go语言实战 : API服务器 (8) 中间件

为什么需要中间件

我们可能需要对每个请求/返回做一些特定的操作,比如

  • 记录请求的 log 信息
  • 在返回中插入一个 Header
  • 部分接口进行鉴权
    这些都需要一个统一的入口。这个功能可以通过引入 middleware 中间件来解决。Go 的 net/http 设计的一大特点是特别容易构建中间件。apiserver 所使用的 gin 框架也提供了类似的中间件。

gin里面的中间件

在 gin 中可以设置 3 种类型的 middleware:

  • 全局中间件
router := gin.New()
// 添加自定义的 logger 中间件
router.Use(middleware.Logger(), gin.Recovery())
  • 单个路由中间件
userRouter.GET("/profile/", middleware.Auth(), handler.UserProfile)
userRouter.POST("/update", middleware.Auth(), handler.UpdateUserProfile)
  • 群组中间件
authorized := router.Group("/", MyMiddelware())
// 或者这样用:
authorized := router.Group("/")
authorized.Use(MyMiddelware())
{authorized.POST("/login", loginEndpoint)
}

在请求和返回的 Header 中插入 X-Request-Id

X-Request-Id 值为 32 位的 UUID,用于唯一标识一次 HTTP 请求

func RequestId() gin.HandlerFunc{return func(c *gin.Context) {requestId := c.Request.Header.Get("X-Request-Id")if requestId==""{v4:= uuid.NewV4()requestId=v4.String()}c.Set("X-Request-Id", requestId)c.Writer.Header().Set("X-Request-Id", requestId)c.Next()}

日志中间件

  1. 获取请求路径,并且进行匹配(只对业务逻辑进行日志记录)
		path := c.Request.URL.Pathreg:= regexp.MustCompile("(/v1/user|/login)")if !reg.MatchString(path) {return}// Skip for the health check requests.if path == "/sd/health" || path == "/sd/ram" || path == "/sd/cpu" || path == "/sd/disk" {return}
  1. 获取请求中的IP等信息,并且给请求重新赋值(请求读取完会被置空)
		var  bodys []byteif c.Request.Body!=nil{bodys, _ = ioutil.ReadAll(c.Request.Body)}c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodys))method := c.Request.Methodip := c.ClientIP()
  1. 将响应重定向到指定IO流,并且提取里面的信息
		blw := &bodyLogWriter{body:           bytes.NewBufferString(""),ResponseWriter: c.Writer,}c.Writer=blwc.Next()var response handler.Responseif err := json.Unmarshal(blw.body.Bytes(), &response); err != nil {log.Println(err, "response body can not unmarshal to model.Response struct, body: %s", string(blw.body.Bytes()))code = errno.InternalServerError.Codemessage = err.Error()} else {code = response.Codemessage = response.Message}}
       func (w bodyLogWriter) Write(b []byte) (int, error) {w.body.Write(b)return w.ResponseWriter.Write(b)
  1. 将从请求与响应中提取的信息进行输出
	log.Printf("%-13s | %-12s | %s %s | {code: %d, message: %s}", sub, ip, pad.Right(method, 5, ""), path, code, message)

测试

X-Request-id

可以看到,HTTP 返回的 Header 有 32 位的 UUID:
image.png

日志

每个请求的日志信息分为4个部分

  • 耗时
  • 请求 IP
  • HTTP 方法 HTTP 路径
  • 返回的 Code 和 Message
    image.png

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

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

相关文章

缺失值和异常值的识别与处理_识别异常值-第一部分

缺失值和异常值的识别与处理📈Python金融系列 (📈Python for finance series) Warning: There is no magical formula or Holy Grail here, though a new world might open the door for you.警告 : 这里没有神奇的配方或圣杯,尽管…

leetcode 664. 奇怪的打印机(dp)

题目 有台奇怪的打印机有以下两个特殊要求: 打印机每次只能打印由 同一个字符 组成的序列。 每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符。 给你一个字符串 s ,你的任务是计算这个打印机打印它需要的最少打印次数。…

PHP7.2 redis

为什么80%的码农都做不了架构师?>>> PHP7.2 的redis安装方法: 顺便说一下PHP7.2的安装: wget http://cn2.php.net/distributions/php-7.2.4.tar.gz tar -zxvf php-7.2.4.tar.gz cd php-7.2.4./configure --prefix/usr/local/php…

梯度 cv2.sobel_TensorFlow 2.0中连续策略梯度的最小工作示例

梯度 cv2.sobelAt the root of all the sophisticated actor-critic algorithms that are designed and applied these days is the vanilla policy gradient algorithm, which essentially is an actor-only algorithm. Nowadays, the actor that learns the decision-making …

垃圾回收算法优缺点对比

image.pngGC之前 说明:该文中的GC算法讲解不仅仅局限于某种具体开发语言。 mutator mutator 是 Edsger Dijkstra 、 琢磨出来的词,有“改变某物”的意思。说到要改变什么,那就是 GC 对象间的引用关系。不过光这么说可能大家还是不能理解&…

yolo人脸检测数据集_自定义数据集上的Yolo-V5对象检测

yolo人脸检测数据集计算机视觉 (Computer Vision) Step by step instructions to train Yolo-v5 & do Inference(from ultralytics) to count the blood cells and localize them.循序渐进的说明来训练Yolo-v5和进行推理(来自Ultralytics )以对血细胞进行计数并将其定位。 …

图深度学习-第2部分

有关深层学习的FAU讲义 (FAU LECTURE NOTES ON DEEP LEARNING) These are the lecture notes for FAU’s YouTube Lecture “Deep Learning”. This is a full transcript of the lecture video & matching slides. We hope, you enjoy this as much as the videos. Of cou…

Linux下 安装Redis并配置服务

一、简介 1、 Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问。 2、 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 3、 Redis支持数据的备份,即mas…

leetcode 477. 汉明距离总和(位运算)

theme: healer-readable 题目 两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。 计算一个数组中,任意两个数之间汉明距离的总和。 示例: 输入: 4, 14, 2 输出: 6 解释: 在二进制表示中,4表示为0100,14表示为1110&…

量子信息与量子计算_量子计算为23美分。

量子信息与量子计算On Aug 13, 2020, AWS announced the General Availability of Amazon Braket. Braket is their fully managed quantum computing service. It is available on an on-demand basis, much like SageMaker. That means the everyday developer and data scie…

全面理解Java内存模型

Java内存模型即Java Memory Model,简称JMM。JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的。 如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。Java内存模型定义了多…

leetcode 1074. 元素和为目标值的子矩阵数量(map+前缀和)

给出矩阵 matrix 和目标值 target&#xff0c;返回元素总和等于目标值的非空子矩阵的数量。 子矩阵 x1, y1, x2, y2 是满足 x1 < x < x2 且 y1 < y < y2 的所有单元 matrix[x][y] 的集合。 如果 (x1, y1, x2, y2) 和 (x1’, y1’, x2’, y2’) 两个子矩阵中部分坐…

失物招领php_新奥尔良圣徒队是否增加了失物招领?

失物招领phpOver the past couple of years, the New Orleans Saints’ offense has been criticized for its lack of wide receiver options. Luckily for Saints’ fans like me, this area has been addressed by the signing of Emmanuel Sanders back in March — or has…

leetcode 5756. 两个数组最小的异或值之和(状态压缩dp)

题目 给你两个整数数组 nums1 和 nums2 &#xff0c;它们长度都为 n 。 两个数组的 异或值之和 为 (nums1[0] XOR nums2[0]) (nums1[1] XOR nums2[1]) … (nums1[n - 1] XOR nums2[n - 1]) &#xff08;下标从 0 开始&#xff09;。 比方说&#xff0c;[1,2,3] 和 [3,2,1…

客户细分模型_Avarto金融解决方案的客户细分和监督学习模型

客户细分模型Lets assume that you are a CEO of a company which have some X amount of customers in a city with 1000 *X population. Analyzing the trends/features of your customer and segmenting the population of the city to land new potential customers would …

leetcode 231. 2 的幂

给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果存在一个整数 x 使得 n 2x &#xff0c;则认为 n 是 2 的幂次方。 示例 1&#xff1a; 输入&#xff1a;n 1 输出&#xff1a;tr…

leetcode 342. 4的幂

给定一个整数&#xff0c;写一个函数来判断它是否是 4 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 4 的幂次方需满足&#xff1a;存在整数 x 使得 n 4x 示例 1&#xff1a; 输入&#xff1a;n 16 输出&#xff1a;true …

梯度反传_反事实政策梯度解释

梯度反传Among many of its challenges, multi-agent reinforcement learning has one obstacle that is overlooked: “credit assignment.” To explain this concept, let’s first take a look at an example…在许多挑战中&#xff0c;多主体强化学习有一个被忽略的障碍&a…

大数据与Hadoop

大数据的定义 大数据是指无法在一定时间内用常规软件工具对其内容进行抓取、管理和处理的数据集合。 大数据的概念–4VXV 1,数据量大&#xff08;Volume&#xff09;2,类型繁多&#xff08;Variety &#xff09;3,速度快时效高&#xff08;Velocity&#xff09;4,价值密度低…

facebook.com_如何降低电子商务的Facebook CPM

facebook.comWith the 2020 election looming, Facebook advertisers and e-commerce stores are going to continually see their ad costs go up as the date gets closer (if they haven’t already).随着2020年选举的临近&#xff0c;随着日期越来越近&#xff0c;Facebook…