15分钟学 Go 第 41 天:中间件的使用

第41天:中间件的使用

目标:学习如何在Go语言的Web服务中使用中间件

中间件(Middleware)是Web开发中的一种常见设计模式,通常用于处理请求和响应过程中的一些共通功能。比如:日志记录、认证授权、请求处理、响应修改等。在Go语言的Web开发中,中间件是通过装饰器模式实现的,可以帮助我们在请求处理流程中插入额外的操作。

本节内容将带领你详细学习Go语言中如何使用中间件,尤其是在Web服务中。我们会通过以下几个方面来阐述这一主题:

  1. 中间件的定义和用途
  2. Go语言中间件的实现
  3. Go标准库net/http中的中间件实现
  4. 基于gorilla/mux的中间件实现
  5. 常见中间件案例:日志记录、身份验证、跨域处理
  6. 中间件执行流程图

1. 中间件的定义和用途

在Web应用程序中,中间件通常是指位于客户端请求和服务器响应之间的一个或多个处理组件。这些组件可以:

  • 修改请求:比如添加请求头、解析请求体等。
  • 控制请求流:比如进行身份验证,检查用户是否有权限访问某些资源。
  • 记录日志:记录访问日志、错误日志等。
  • 修改响应:如修改返回的内容、设置响应头等。

中间件的特点是,它是独立的功能单元,能够插入到请求处理链的任意位置,并且每个中间件组件只负责某一特定功能。


2. Go语言中间件的实现

在Go语言中,中间件通常是一个函数,它接收一个http.Handler接口类型的参数,返回一个新的http.Handler,通常在返回的新http.Handler中会对请求或响应进行处理。

Go中间件的一般签名如下:

type Middleware func(http.Handler) http.Handler

其中,http.Handler是Go语言标准库中定义的接口类型,用于处理HTTP请求。中间件的作用是将请求传递到下一个处理器。

3. Go标准库net/http中的中间件实现

Go标准库中的net/http包是处理HTTP请求和响应的核心。我们可以通过定义一个函数来实现中间件。

下面是一个简单的示例,展示了如何在Go语言中使用中间件进行日志记录:

示例代码:简单的日志记录中间件
package mainimport ("fmt""log""net/http""time"
)// 定义中间件类型
type Middleware func(http.Handler) http.Handler// 日志记录中间件
func LoggingMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {start := time.Now()log.Printf("Started %s %s", r.Method, r.URL.Path)next.ServeHTTP(w, r)log.Printf("Completed in %v", time.Since(start))})
}// 处理请求的实际处理器
func HelloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello, World!")
}func main() {// 创建一个路由器mux := http.NewServeMux()// 将处理器注册到路由器mux.HandleFunc("/", HelloHandler)// 包裹中间件handler := LoggingMiddleware(mux)// 启动HTTP服务器log.Fatal(http.ListenAndServe(":8080", handler))
}
代码解析
  • LoggingMiddleware是我们定义的日志中间件,它接收一个http.Handler,并返回一个新的http.Handler
  • HelloHandler是一个简单的请求处理函数,当访问根路径时返回“Hello, World!”。
  • LoggingMiddleware会在请求开始时记录请求的路径和方法,然后调用next.ServeHTTP(w, r)来将请求传递给下一个处理器,最后记录请求的处理时间。

运行该代码后,在终端你会看到类似以下的日志:

Started GET /
Completed in 500ns

4. 基于gorilla/mux的中间件实现

gorilla/mux是一个非常流行的Go语言路由器,它支持中间件的功能,能够让我们更方便地组织和使用中间件。

下面是一个使用gorilla/mux的中间件示例:

示例代码:基于gorilla/mux的中间件实现
package mainimport ("fmt""log""net/http""time""github.com/gorilla/mux"
)// 日志记录中间件
func LoggingMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {start := time.Now()log.Printf("Started %s %s", r.Method, r.URL.Path)next.ServeHTTP(w, r)log.Printf("Completed in %v", time.Since(start))})
}// 处理请求的实际处理器
func HelloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello, Gorilla Mux!")
}func main() {// 创建一个mux路由r := mux.NewRouter()// 将处理器注册到路由器r.HandleFunc("/", HelloHandler).Methods("GET")// 包裹中间件r.Use(LoggingMiddleware)// 启动HTTP服务器log.Fatal(http.ListenAndServe(":8080", r))
}
代码解析
  • 我们通过mux.NewRouter()创建了一个新的路由器。
  • 使用r.Use(LoggingMiddleware)将日志记录中间件应用到整个路由器。
  • 在请求被处理前和处理后,都会通过LoggingMiddleware记录日志信息。

运行该代码,访问http://localhost:8080/,你会看到与上一个示例类似的日志输出。


5. 常见中间件案例

除了日志记录中间件,Web开发中还有一些其他常见的中间件,我们将在此列举并展示如何在Go中实现。

1. 认证和授权中间件

认证中间件用于验证用户是否已登录或是否拥有访问某些资源的权限。下面是一个简单的身份验证中间件:

func AuthMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {authHeader := r.Header.Get("Authorization")if authHeader == "" {http.Error(w, "Forbidden", http.StatusForbidden)return}// 假设我们只是简单地检查一个固定的tokenif authHeader != "Bearer secret-token" {http.Error(w, "Forbidden", http.StatusForbidden)return}next.ServeHTTP(w, r)})
}
2. 跨域资源共享(CORS)中间件

CORS中间件用于处理跨域请求,它通常会添加Access-Control-Allow-Origin等头信息,允许来自其他域的请求。

func CORSMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {w.Header().Set("Access-Control-Allow-Origin", "*")w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")w.Header().Set("Access-Control-Allow-Headers", "Content-Type")next.ServeHTTP(w, r)})
}
3. 请求限流中间件

请求限流中间件用于限制客户端的请求频率,防止服务器过载。可以根据具体需求实现如IP限流、用户限流等策略。


6. 中间件执行流程图

我们通过以下的流程图来帮助理解Go Web服务中中间件的执行顺序:

┌────────────────────────┐
│        请求到达         │
└────────────────────────┘│▼┌─────────────────────┐│  进入第一个中间件      │└─────────────────────┘│▼┌─────────────────────┐│  第一个中间件处理      │└─────────────────────┘│▼┌───────────────────┐│  进入第二个中间件    │└───────────────────┘│▼┌───────────────────┐│  第二个中间件处理    │└───────────────────┘│▼┌────────────────┐│  请求到达处理器  │└────────────────┘│▼┌────────────────┐│  返回响应       │└────────────────┘│▼┌───────────────────┐│  进入响应中间件     │└───────────────────┘│▼┌───────────────────┐│  响应中间件处理     │└───────────────────┘│▼┌────────────────┐│  响应发送给客户端 │└────────────────┘

总结

中间件是Go语言Web开发中非常重要的组成部分,能够帮助我们处理请求、响应,增加一些通用的功能。在本节中,我们深入探讨了Go语言如何实现中间件,涵盖了日志记录、中间件链、认证授权等实际应用。希望你能通过这些示例理解中间件的工作原理,并能够在自己的Web项目中灵活使用。


怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

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

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

相关文章

# filezilla连接 虚拟机ubuntu系统出错“尝试连接 ECONNREFUSED - 连接被服务器拒绝, 失败,无法连接服务器”解决方案

filezilla连接 虚拟机ubuntu系统出错“尝试连接 ECONNREFUSED - 连接被服务器拒绝, 失败,无法连接服务器”解决方案 一、问题描述: 当我们用filezilla客户端 连接 虚拟机ubuntu系统时,报错“尝试连接 ECONNREFUSED - 连接被服务…

TCP编程API

这里写自定义目录标题 主要的 TCP 编程 API 函数1.1 socket()1.2 bind()1.3 listen()1.4 accept()1.5 connect()1.6 send()1.7 recv()1.8 close() 主要的 TCP 编程 API 函数 1.1 socket() 创建一个新的套接字。 int socket(int domain, int type, int protocol);domain&…

STM32WB55RG开发(1)----开发板测试

STM32WB55RG开发----1.开发板测试 概述硬件准备视频教学样品申请源码下载产品特性参考程序生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32WB55 & SENSOR是一款基于STM32WB55系列微控制器的评估套件。该套件采用先进的无线通信技术,支…

人工智能、机器学习与深度学习:层层递进的技术解读

引言 在当今科技快速发展的时代,人工智能(AI)已经成为一个热门话题,几乎渗透到了我们生活的方方面面。从智能手机的语音助手,到自动驾驶汽车,再到医疗诊断中的图像识别,人工智能的应用正在改变我…

【Java学习】电脑基础操作和编程环境配置

CMD 在Windows中用命令行的方式操作计算机。 打开CMD Win R输入CMD按下回车键 Win E 进入我的电脑 常用的CMD命令 盘符名称冒号 说明:盘符切换 举例:E:回车,表示切换到E盘 dir 说明:查看当前路径下的内容 cd目录 说明&a…

Mac中禁用系统更新

Mac中禁用系统更新 文章目录 Mac中禁用系统更新1. 修改hosts,屏蔽系统更新检测联网1. 去除系统偏好设置--系统更新已有的小红点标记 1. 修改hosts,屏蔽系统更新检测联网 打开终端,执行命令: sudo vim /etc/hosts127.0.0.1 swdis…

Unity3D UI 双击和长按

Unity3D 实现 UI 元素双击和长按功能。 UI 双击和长按 上一篇文章实现了拖拽接口,这篇文章来实现 UI 的双击和长按。 双击 创建脚本 UIDoubleClick.cs,创建一个 Image,并把脚本挂载到它身上。 在脚本中,继承 IPointerClickHa…

sql专题 之 where和join on

文章目录 前言where介绍使用过滤结果集关联两个表 连接外连接内连接自然连接 使用inner join和直接使用where关联两个表的区别总结 前言 从数据库查询数据时,一张表不足以查询到我们想要的数据,更多的时候我们需要联表查询。 联表查询我们一般会使用连接…

LeetCode 热题100之 动态规划1

对于动态规划的问题,解题步骤有以下几部(总结为动态规划五部曲:参考代码随想录动态规划 确定dp数组以及下标的含义;确定递推公式;dp数组如何初始化;确定遍历顺序;举例推导dp数组 下面的解题思路分析都将从…

python可视化将多张图整合到一起(画布)

这周有点事忙着,没时间重温刚结束的Mathurcup数学建模,这两天也是再看了下,论文还是赶紧挺烂的,但比国赛又有进步(说起国赛又不得不抱怨了,基本其余省份都发了,但江西......哎)。哎&…

MFC图形函数学习07——画扇形函数

绘制扇形函数是MFC中绘图的基本函数,它绘制的仍是由椭圆弧与椭圆中心连线构成的椭圆扇形,特例是由圆弧与圆心连线构成的圆扇形。 一、绘制扇形函数 原型:BOOL Pie(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); …

vue 依赖注入(Provide、Inject )和混入(mixins)

Prop 逐级透传问题​ 通常情况下,当我们需要从父组件向子组件传递数据时,会使用 props。想象一下这样的结构:有一些多层级嵌套的组件,形成了一棵巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。…

手机上用什么方法可以切换ip

手机上用什么方法可以切换IP?在某些特定情境下,用户可能需要切换手机的IP地址,以满足网络安全、隐私保护或绕过地域限制等需求。下面以华为手机为例,将详细介绍手机IP地址切换的几种方法,帮助用户轻松实现这一目标。 一…

一个强大的Stable Diffusion comfyUI 工作流,能实现写真自由、各种风格融合、面部特征一致性等等

今天,我们将向您介绍一款非常实用的工具——Stable Diffusion comfyUI工作流。这款工作流基于Stable Diffusion技术,旨在为您提供一键式生成图像的便捷体验。无论您是AI绘画的新手还是专业人士,这个工作流都能为您带来极大的便利。 在这个教…

外泌体相关基因肝癌临床模型预测——2-3分纯生信文章复现——6.外泌体基因功能注释(二)

内容如下: 1.外泌体和肝癌TCGA数据下载 2.数据格式整理 3.差异表达基因筛选 4.预后相关外泌体基因确定 5.拷贝数变异及突变图谱 6.外泌体基因功能注释 7.LASSO回归筛选外泌体预后模型 8.预后模型验证 9.预后模型鲁棒性分析 10.独立预后因素分析及与临床的相关性分析…

【Homework】【1--4】Learning resources for DQ Robotics in MATLAB

Learning resources for DQ Robotics in MATLAB Lesson 1 代码 % Step 2: Define the real numbers a1 and a2 a1 123; a2 321;% Step 3: Calculate and display a3 a1 a2 a3 a1 a2; disp([a3 (a1 a2) , num2str(a3)])% Step 4: Calculate and display a3 a1 * a2 a3…

linux命令详解,存储管理相关

存储管理 一、内存使用量,free free 命令是一个用于显示系统中物理内存(RAM)和交换空间(swap)使用情况的工具 free -m free -m -s 5参数 -b 功能: 以字节(bytes)为单位显示内存使用情况。说…

推荐一款功能强大的视频修复软件:Apeaksoft Video Fixer

Apeaksoft Video Fixer是一款功能强大的视频修复软件,专门用于修复损坏、不可播放、卡顿、画面失真、黑屏等视频问题。只需提供一个准确且有效的样本视频作为参考,该软件就能将受损视频修复到与样本视频相同的质量。该软件目前支持MP4、MOV、3GP等格式的…

Redis如何保证数据不丢失(可靠性)

本文主要以学习为主,详细参考:微信公众平台 Redis 保证数据不丢失的主要手段有两个: 持久化 多机部署 我们分别来看它们两的具体实现细节。 1.Redis 持久化 持久化是指将数据从内存中存储到持久化存储介质中(如硬盘&#xf…

第三十九章 基于VueCli自定义创建项目

目录 1. 选择创建模式 2. 选择需要的功能 3. 选择历史模式还是哈希模式 ​4.CSS预处理器 5. 选择ESLint规则 6. 开始创建项目 ​7. 自定义项目最终结构 1. 选择创建模式 输入创建的项目名,创建项目: 这里选择自定义模式: 2. 选择需要…