RRuna

路由中间件机制

HTTP 中间件的类型、使用位置和执行顺序

中间件用来处理横切逻辑,比如日志、错误恢复、限流、认证、安全 Header、请求 ID、CSRF 防护。

这篇只说明 route 的中间件机制。官方内置中间件、security 预设和业务中间件见 中间件总览

中间件是什么

Runa 的中间件类型是:

type Middleware func(route.Handler) route.Handler

可以理解成:中间件接收下一个 handler,返回一个新的 handler。

编写中间件

func Trace() route.Middleware {
    return func(next route.Handler) route.Handler {
        return func(ctx *route.Context) error {
            ctx.Response().Header().Set("X-Trace", "demo")
            return next(ctx)
        }
    }
}

这段中间件会给响应加上 X-Trace Header,然后继续执行后面的 handler。

在哪里使用中间件

全局使用:

route.Default().Use(Trace())

分组使用:

api := route.Default().Group("/api")
api.Use(Trace())

单个路由使用:

route.Default().Get("/profile", profile).Use(Trace())

执行顺序

route.Default().Use(A(), B(), C())

执行过程:

A before -> B before -> C before -> handler -> C after -> B after -> A after

先注册的中间件在最外层,最后结束。

一个带前后逻辑的例子

func Logger() route.Middleware {
    return func(next route.Handler) route.Handler {
        return func(ctx *route.Context) error {
            start := time.Now()
            err := next(ctx)
            log.Println(ctx.Request().Method, ctx.Request().URL.Path, time.Since(start))
            return err
        }
    }
}

内置中间件

  • 内置中间件:recover、CORS、CSRF、bodylimit、timeout、requestid、realip、logger、healthcheck、static、helmet
  • 安全预设:生产环境常用中间件组合
  • 业务中间件:session、auth、rate、audit

常见错误

忘记 return next(ctx)

如果中间件没有调用 next(ctx),后面的中间件和最终 handler 都不会执行。这可以用于拦截请求,但要确认是故意的。

中间件里吞掉错误

通常应该把 next(ctx) 返回的错误继续返回,让统一错误处理接管。

编辑此页