buffalo cli 不提供 buffalo g middleware 命令,中间件需手动创建于 actions/ 目录下,类型为 buffalo.middlewarefunc,注册时须在 app.use() 中置于路由定义前,且注意执行顺序与依赖初始化时机。

buffalo g middleware 命令不存在,别白试
Buffalo CLI 没有 buffalo g middleware 这个命令,运行它会直接报 command not found: middleware。框架不提供中间件生成器,所有中间件都得手写——这不是遗漏,是设计取舍:中间件逻辑差异大、复用场景有限,自动生成反而容易误导。
手动创建中间件的正确位置和签名
中间件本质是 Go 的 http.Handler 或 Buffalo 的 buffalo.MiddlewareFunc,必须放在 actions/ 目录下(如 actions/auth.go),否则 buffalo dev 不会加载它。
推荐用 buffalo.MiddlewareFunc 类型,兼容性好、能访问 buffalo.Context:
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
func AuthMiddleware(next buffalo.Handler) buffalo.Handler {
return func(c buffalo.Context) error {
token := c.Request().Header.Get("Authorization")
if token == "" {
return c.Error(401, errors.New("missing auth token"))
}
// 验证逻辑...
return next(c)
}
}
- 函数名必须首字母大写(如
AuthMiddleware),否则包外不可见 - 不能放在
main.go或models/下,buffalo dev只扫描actions/ - 不要在中间件里调用
c.Render()或c.JSON()后还执行next(c),会导致重复写响应
怎么注册中间件才生效
注册必须在 actions/app.go 的 App() 函数里,且顺序关键:
func App() *buffalo.App {
if app == nil {
app = buffalo.New(buffalo.Options{
Env: ENV,
SessionName: "_myapp_session",
})
app.Use(middleware.PopTransaction(models.DB))
app.Use(AuthMiddleware) // ← 放在这里,早于路由匹配
app.Resource("/users", UsersResource{})
}
return app
}
-
app.Use()必须在app.Resource()或app.GET()之前,否则中间件不会被路由链触发 - 如果中间件依赖 DB(比如查 token),要确保它在
PopTransaction之后注册,否则c.Value("tx")为空 - 全局中间件对所有路由生效;若只想作用于某组路由,需手动包装 handler:
app.GET("/api/users", AuthMiddleware(UsersHandler))
常见踩坑点:中间件不执行或 panic
最常遇到的不是写错逻辑,而是环境或时机问题:
-
buffalo dev启动后改了中间件代码但没热重载?检查actions/下是否有多余的.go文件(比如备份的auth_old.go),buffalo 会尝试编译所有文件,语法错误直接导致启动失败 - 中间件里用了
models.DB却 panic?确认models/models.go中init()已正确初始化连接,且app.Use()没写在models.DB初始化之前 - 想调试中间件却看不到日志?加一行
log.Printf("→ AuthMiddleware hit for %s", c.Request().URL.Path),但别用c.Logger()—— 它在中间件注册前未初始化 - 返回 500 但没错误信息?在中间件末尾加
defer func() { if r := recover(); r != nil { log.Printf("panic in middleware: %v", r) } }()
中间件没有“模板”可套,每个都要贴着业务逻辑写;真正难的不是语法,而是决定它该在中间件链里站哪一环、是否该短路、以及怎么跟现有事务或 session 协作。










