Echo框架 中间件

在 Go Echo框架中 中间件(Middleware)指的是可以拦截http请求-响应生命周期的特殊函数。在请求-响应生命周期中可以注册多个中间件,每个中间件执行不同的功能,一个中间执行完再轮到下一个中间件执行。

 

1. 中间件的运行流程

下图是中间件的运行流程:

 

2. 中间件常见的应用场景

中间件常见的应用场景如下:

  • 请求限速
  • api接口签名处理
  • 权限校验
  • 统一错误处理

如果你想拦截所有请求做一些事情都可以开发一个中间件函数去实现。

 

3. Redirect 中间件

Redirect 重定向中间件支持下面几种重定向机制:

  • http 强制跳转至 https
    比如:
    访问http://www.codebaoku.com 自动跳转到 https://www.codebaoku.com
e := echo.New()
e.Pre(middleware.HTTPSRedirect())
  • www 跳转
    比如:
    访问http://codebaoku.com 自动跳转到http://www.codebaoku.com
e := echo.New()
e.Pre(middleware.WWWRedirect())
  • https www 跳转
    比如:
    访问http://coebaoku.com 自动跳转到https://www.codebaoku.com
e := echo.New()
e.Pre(middleware.HTTPSWWWRedirect())

 

4. Recover 中间件

Recover 中间件,主要用于拦截 panic 错误并且在控制台打印错误日志,避免 echo 程序直接崩溃。
使用范例如下:

//初始化echo实例
e := echo.New()

//注册中间件
e.Use(middleware.Recover())

一般 echo 应用都会注册 Recover 中间件,避免程序崩溃退出。

 

5. Static 中间件

Static 中间件主要用于处理 js、css 之类的静态资源, 具体用法请参考: 处理静态文件。

 

6. Logger 中间件

Logger 中间件主要用于打印 http 请求日志。

//初始化echo实例
e := echo.New()

//注册中间件
e.Use(middleware.Logger())

开启 Logger 中间件后,访问 http 请求会打印下面日志:

{"time":"2017-01-12T08:58:07.372015644-08:00","remote_ip":"::1","host":"localhost:1323","method":"GET","uri":"/","status":200,"error":"","latency":14743,"latency_human":"14.743µs","bytes_in":0,"bytes_out":2}

 

7. Rewrite 中间件

url 重定向中间件,我们可以用于将一个 url 重定向到另外一个 url。
范例如下:

//初始化echo实例
e := echo.New()

e.Pre(middleware.Rewrite(map[string]string{
  "/old":              "/new",   // 将 /old重定向至 /new
  "/api/*":            "/$1",    
  "/js/*":             "/public/javascripts/$1",
  "/users/*/orders/*": "/user/$1/order/$2",
}))

"*"星代表任意字符串,$1 代表引用表达式中第一个星(*)的匹配值,$2 代表第二个,以此类推。

 

8. Session 中间件

会话中间件,请参考 session 处理章节。

 

9. 自定义中间件

下面以一个简单的统计访问量的例子介绍如何自定义中间件。

package main

import (
	"net/http"
	"github.com/labstack/echo"
)

//记录访问量
var totalRequests  = 0

//中间件函数
func Count(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		//在这里处理拦截请求的逻辑
		//累计访问量
		totalRequests++
		
		//在响应头中输出访问量
		c.Response().Header().Add("requests", fmt.Sprintf("%d", totalRequests))

		//执行下一个中间件或者执行控制器函数, 然后返回执行结果
		return next(c)
	}
}

func main() {
	//初始化echo实例
	e := echo.New()
	//注册中间件
	e.Use(Count)
	
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	
	e.Logger.Fatal(e.Start(":1323"))
}

Go Echo框架提供了获取 IP地址 的函数:ExtractIPDirect 和 ExtractIPFromXFFHeader。