我的编程空间,编程开发者的网络收藏夹
学习永远不晚

在 Golang 中实现一个简单的Http中间件过程详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

在 Golang 中实现一个简单的Http中间件过程详解

本文主要针对Golang的内置库 net/http 做了简单的扩展,通过添加中间件的形式实现了管道(Pipeline)模式,这样的好处是各模块之间是低耦合的,符合单一职责原则,可以很灵活的通过中间件的形式添加一些功能到管道中,一次请求和响应在管道中的执行过程如下

首先, 我定义了三个测试的中间件 Middleware1,2,3 如下


func Middleware1(next http.Handler) http.Handler {

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("M1 in")
		next.ServeHTTP(w, r)
		fmt.Println("M1 out")
	})

}

func Middleware2(next http.Handler) http.Handler {

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("M2 in")
		next.ServeHTTP(w, r)
		fmt.Println("M2 out")
	})

}

func Middleware3(next http.Handler) http.Handler {

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("M3 in")
		next.ServeHTTP(w, r)
		fmt.Println("M3 out")
	})

}

这里中间件的入参和出参的类型都是 http.Handler, 然后在 next.ServeHTTP() 的前后分别输出了 In 和 Out.

接下来,定义一个 Pipeline 的方法,里面使用嵌套的形式, 使用了上面定义的三个测试的中间件.


func Pipeline(next http.Handler) http.Handler {

	return Middleware1(Middleware2(Middleware3(next)))

}

然后还需要业务代码,这里我定义了 LoginHandler 和 RegisterHandler 两个方法


func LoginHandler(w http.ResponseWriter, r *http.Request) {

	fmt.Println("Login...")
	w.Write([]byte("Login..."))

}

func RegisterHandler(w http.ResponseWriter, r *http.Request) {

	fmt.Println("Register...")
	w.Write([]byte("Register..."))

}

最后修改程序的 main 函数, 在 Login 接口上使用上面添加过中间件的 Pipeline


func main() {

	http.Handle("/Login", Pipeline(http.HandlerFunc(LoginHandler)))

	http.Handle("/Register", http.HandlerFunc(RegisterHandler))

	http.ListenAndServe(":8080", nil)

}

启动程序后,访问 http://localhost:8080/Login, 程序的输出如下,这和本文最上面的管道的流程图是一致的,然后访问 Register 接口, 控制台没有输出信息,当然也不会执行任何中间件。

现在已经实现了中间件的机制,但是,上面添加中间件是用嵌套的方法,这种方式不能说不太优雅,只能说非常的Low,接下来我们需要对管道进行优化


type Chain struct {
	middlewares []func(handler http.Handler) http.Handler
}


func Pipeline(next http.Handler) http.Handler {

	//return Middleware1(Middleware2(Middleware3(next)))

	return AddMiddlewares(Middleware1,Middleware2,Middleware3).Then(next)

} 


func AddMiddlewares(m ...func(handlerFunc http.Handler) http.Handler) Chain {

	c := Chain{}

	c.middlewares = append(c.middlewares,m...)

	return c

}


func (c Chain) Then(next http.Handler) http.Handler {

	for i := range c.middlewares {

		prev := c.middlewares[len(c.middlewares)-1-i]

		next = prev(next)
	}

	return next
} 

首先定义了一个Chain 的struct,用来接收添加到管道中的中间件,在 AddMiddlewares() 函数中,接收了多个Handle, 然后组装到 Chain 对象并返回, 接下来调用 Then() 函数, 把管道中的中间件和业务的Handler 关联起来。在中间件的使用方式上, 这两种方法都是一样的,只需要调用 Pipeline() 方法就行了。

本文在go web中简单的实现了中间件的机制,这样带来的好处也是显而易见的,当然社区也有一些成熟的 middleware 组件,包括 Gin 一些Web框架中也包含了 middleware 相关的功能, 希望对您有用.

到此这篇关于在 Golang 中实现一个简单的Http中间件的文章就介绍到这了,更多相关Golang Http中间件内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

在 Golang 中实现一个简单的Http中间件过程详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么在Golang中实现一个简单的Http中间件

本篇内容主要讲解“怎么在Golang中实现一个简单的Http中间件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么在Golang中实现一个简单的Http中间件”吧!本文主要针对Golang的内
2023-06-20

如何在Python中实现一个简单的RPC远程过程调用框架

如何在Python中实现一个简单的RPC远程过程调用框架在分布式系统中,一种常见的通信机制是通过RPC(Remote Procedure Call,远程过程调用)来实现不同进程之间的函数调用。RPC允许开发者像调用本地函数一样调用远程函数,
2023-10-27

如何在Python中实现一个简单的爬虫程序

如何在Python中实现一个简单的爬虫程序随着互联网的发展,数据已成为当今社会最宝贵的资源之一。而爬虫程序则成为了获取互联网数据的重要工具之一。本文将介绍如何在Python中实现一个简单的爬虫程序,并提供具体的代码示例。确定目标网站在开始编
2023-10-22

如何在Java项目中实现一个简单的图片上传功能

如何在Java项目中实现一个简单的图片上传功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。具体如下:import java.io.*;import java.
2023-05-31

详解Android中通过Intent类实现组件间调用的方法

Intent是Android中用来调用其它组件的类,通过Intent,我们可以非常方便的调用Activity,Broadcast Receiver和Service。Intent intent = new Intent(Intent.ACTI
2022-06-06

怎么在小程序中如何实现一个可截断的瀑布流组件

这期内容当中小编将会给大家带来有关怎么在小程序中如何实现一个可截断的瀑布流组件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。瀑布流是一种常见的布局方式,实现的方式有许多,比如直接分两列,然后控制在左右两列
2023-06-28

javascript在一个拖动过程中,释放鼠标键时触发此事件使用什么函数,详细讲解

在JavaScript中,当释放鼠标键时触发"mouseup"事件,用于检测鼠标指针从元素上抬起时的松开操作。通过将事件监听器附加到元素,可以访问事件信息,如鼠标坐标和按下的按钮。在拖放操作中,"mouseup"事件非常有用,可用于检测释放鼠标键并完成拖放动作。实现拖放还需使用"mousedown"(按下鼠标键)和"mousemove"(拖动鼠标)事件。
javascript在一个拖动过程中,释放鼠标键时触发此事件使用什么函数,详细讲解
2024-04-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录