golang http 中间件
golang http 中间件
golang的http中间件的实现 首先实现一个http的handler接口
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type Router struct {
route map[string]Handle
}
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
通过函数包裹的方式实现
中间件v1.0
1.通过匿名函数 将handler包裹起来 然后再 调用传进来的handler。在执行传进来的参数之前
就可以做到记录日志 等一些中间件的功能
2.如果有多个中间件 那么就多个函数 一层一层包裹
func withMiddle(h Handle) Handle {
return func(writer http.ResponseWriter, request *http.Request) {
t := time.Now()
defer func() {
log.Println("time spend is ", time.Since(t))
}()
h(writer, request)
}
}
func (r *Router) Register1(route string, f Handle) {
r.route[route] = withMiddle(f)
}
func (r *Router) Register2(route string, f Handle) {
r.route[route] = withMiddLog(withMiddTime(f))
}
Register("/bench", func(writer http.ResponseWriter, request *http.Request) {
time.Sleep(time.Second)
fmt.Println("bench sleep 1 second")
})
中间件v1.1
注册的时候 可以更加简化一些 通过匿名函数的方式 当然这种方式没有传递参数
只是作为演示用的
func (r *Router) Register(route string, f HandlerFunc) {
r.route[route] = withMiddLog(withMiddTime(func(writer http.ResponseWriter, request *http.Request) {
f()
}))
}
中间件v2.0
针对中间件v1.1中的没法传递 http中的读写参数的问题 可以封装一个context
将http的读写参数都包裹进来 这样就可以很方便的处理读写了
func (r *Server) Register(route string, f HandlerFunc) {
r.route[route] = withMiddLog(withMiddTime(func(writer http.ResponseWriter, request *http.Request) {
f(r.createContext(writer, request))
}))
}
r.Register("/bench", func(c *Context) {
time.Sleep(time.Second)
fmt.Println("bench sleep 1 second")
c.Writer.Write([]byte("hello!\r\n"))
})
golang框架gin中的实现
中间件v3.0
核心理念是将中间件和最后的函数 一视同仁 。通过一个for循环遍历具体的可以参考代码
func (c *Context) Next() {
c.index++
//for中的index++是为了退出循环 否则没法退出
for ; c.index < len(c.middle); c.index++ {
c.middle[c.index](c)
}
}
func withMiddTime() HandleContext {
return func(c *Context) {
t := time.Now()
defer func() {
fmt.Println("withMiddTime end time", time.Since(t))
}()
fmt.Println("withMiddTime start ", time.Since(t))
c.Next()
}
}
func (s *Server) Register(path string, f ...HandleContext) {
handleNew := make([]HandleContext, 0, len(s.handle)+len(f))
handleNew = append(handleNew, s.handle...)
handleNew = append(handleNew, f...)
s.routeHandler(path, func(writer http.ResponseWriter, request *http.Request) {
s.createContext(writer, request, handleNew).Next()
})
}
golang http 中间件的更多相关文章
- 基于gin的golang web开发:中间件
gin中间件(middleware)提供了类似于面向切面编程或路由拦截器的功能,可以在请求前和请求之后添加一些自定义逻辑.实际开发中有很多场景会用到中间件,例如:权限验证,缓存,错误处理,日志,事务等 ...
- 在 Golang 中实现一个简单的Http中间件
本文主要针对Golang的内置库 net/http 做了简单的扩展,通过添加中间件的形式实现了管道(Pipeline)模式,这样的好处是各模块之间是低耦合的,符合单一职责原则,可以很灵活的通过中间件的 ...
- golang程序设计:Go middleware中间件以及Gin 中间件分析
先从业务开发角度出发,来逐渐引出中间件. 一.刚开始时业务开发 开始业务开发时,业务需求比较少. 当我们最开始进行业务开发时,需求不是很多. 第一个需求产是品向大家打声招呼:"hello w ...
- Golang Web入门(3):如何优雅的设计中间件
摘要 在上一篇文章中,我们已经可以实现一个性能较高,且支持RESTful风格的路由了.但是,在Web应用的开发中,我们还需要一些可以被扩展的功能. 因此,在设计框架的过程中,应该留出可以扩展的空间,比 ...
- Golang进阶,揉碎数据库中间件,干货满满!
目录 必读 一.Centos7.Mac安装MySQL 二.主从复制原理 2.1.基于binlog_filename + position 2.2.基于GTID 三.my.cnf 四.测试SQL 五.中 ...
- 【get√】golang新手理解了一点点gin框架的中间件
1.通过use()来使用多个中间件 router := gin.New() router.Use( middleware1, middleware2) 2.中间件的典型实现 func Logger() ...
- golang实现路由中间件middleware
registerHandlers.go package router import ( "../ctrl" "../funcs" "github.co ...
- Golang友团无闻Go语言Web基础视频教程
教程内容:GO语言资料Golang友团无闻Go语言编程基础Golang友团无闻Go语言Web基础教程 Go语言Web基础教程列表:[Go Web基础]12Go Web 扩展学习.mp4[Go Web基 ...
- Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践
目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ? RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...
随机推荐
- 命令行 IRC 客户端 irssi 的基本操作
登录与退出 启动 irssi $ irssi 登陆 IRC 服务器/connect server port 修改昵称/nick nickname 直接带昵称登录指定的服务器$ irssi -c [se ...
- TPU的相关资料
1.谷歌 TPU 的强大与局限:TPU/GPU/CPU性能功耗全面对比:http://www.sohu.com/a/134315786_473283 2.谷歌发布TPU论文,75位联合作者,GPU迎来 ...
- proxy_pass http://127.0.0.1:5000; 502 bad getway
(13: Permission denied) while connecting to upstream:[nginx] I am working with configuring django pr ...
- autofac 注入生命周期
创建实例方法 1.InstancePerDependency 对每一个依赖或每一次调用创建一个新的唯一的实例.这也是默认的创建实例的方式. 官方文档解释:Configure the component ...
- fleet-运行一个全局的单元
运行一个全局的单元 正如前面所提到的,全局单元是有用的,用于在您的集群中的所有机器上运行一个单元.它不会比一个普通的单元差太多,而是一个新的x-fleet参数称为Global=true.这是一个示例单 ...
- Java实现将GBK编码格式的文件夹中所有文件都转化为UTF-8格式的文件,编码格式转化
package CodeConvert; import Java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Fi ...
- Linux shell标准输入,标准输出,错误输出
shell中可能经常能看到:1>/dev/null 2>&1 eg:sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{prin ...
- CAS 配置NLB 负载均衡网络无法连接
在虚拟机与虚拟机.虚拟机与实机之间利用Windows操作系统自带的网络负载均衡功能如选择单播集群模式,网络就无法通讯,NLB不成功. Scenario #1 在虚拟机与虚拟机之间选择多播模式NLB可正 ...
- Git随笔:尝试将本地工程上传至Github上的repository仓库,构建远端与本地协同的Git环境
上传工程至自己的Github公开库,步骤如下: 第1步:建立本地 git 仓库,cd 到你的本地项目根目录下,执行 git init 命令: 第2步:将本地项目工作区的所有文件添加到暂存区.小数点 & ...
- POJ 3252 Round Numbers (区间DP,基础)
题意: 统计区间[L,R]有多少个数,其二进制表示法中的0的个数不少于1的个数?(不允许前缀0) 思路: 状态表示为 [当前第几位][总位数][1的个数],最后判断一下1的个数是否满足条件,要注意前导 ...