手动注册路由(如app.GET)适用于单端点、纯JSON响应等简单场景,必须在app.Serve()前完成;Resource适合RESTful标准路由但路径和命名敏感;参数路由需严格匹配占位符格式;特殊路由需绕过中间件。

直接在 routes/app.go 里写 app.GET、app.POST 最快,但想少写重复代码就用 app.Resource;别在中间件里注册路由,也别漏掉 app.Serve() 前的时机。
手动注册单个路由:什么时候该用 app.GET 而不是 Resource
当你只需要一个端点(比如 /healthz)、返回纯 JSON、不涉及模板或表单逻辑时,手动注册最干净。它不依赖控制器命名约定,也不生成多余路由。
-
app.GET("/healthz", func(c buffalo.Context) error { return c.Render(200, r.JSON(map[string]string{"status": "ok"})) })—— 这种写法没有隐含行为,调试时一眼看清路径和响应 - 注意:所有手动路由必须放在
app.Serve()调用之前,否则启动后完全不可达 - 别把路由注册写在中间件函数里——中间件只处理已匹配的请求,不能动态加路由
- 如果用了
Group()分组,记得用分组变量调用.GET,而不是app.GET,否则前缀失效
app.Resource 自动生成 REST 路由:路径写错一个斜杠就全挂
app.Resource("/users", UsersResource{}) 会一口气注册 7 个标准路径(GET /users、POST /users 等),但它对路径格式极其敏感。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 路径前缀不能以斜杠结尾:
"/users/"→ 所有非 GET 请求(如 POST)返回 404;必须写成"/users" - 控制器结构体名必须与 resource 名一致,且首字母大写:
UsersResource对应actions/users.go中的type UsersResource struct{} - 方法名只能是
List、Show、Create、Update、Destroy、New、Edit之一;拼错(比如list小写)→ 404 且无日志提示 - 生成命令
buffalo generate resource users会自动创建文件+路由注册语句,但你要检查生成的routes/app.go是否真被插入到了App.Routes()函数内
带参数的路由怎么写:冒号声明和 c.Param 必须配对
路径参数不是“自动识别”的,必须在注册时显式声明占位符,否则 c.Param("id") 永远返回空字符串。
- 正确写法:
app.GET("/users/:id", UserShow);错误写法:app.GET("/users/{id}", ...)或app.GET("/users/:id/", ...)(末尾斜杠会导致参数提取失败) -
c.Param("id")返回的是 string,必须自己转类型:id, err := strconv.Atoi(c.Param("id")),漏掉err != nil判断 → 请求/users/abc直接 panic - 不要混用路径参数和查询参数:比如
/users/:id?format=json,后者要用c.Request().URL.Query().Get("format")提取 - 多个路径参数要一一对应:
app.GET("/posts/:year/:month/:day", PostByDate)→c.Param("year")、c.Param("month")、c.Param("day")才有效
微信回调、WebSocket 等特殊路由:绕过中间件是硬要求
这类路由对 HTTP 协议细节敏感,Buffalo 默认中间件(尤其是 CSRF、gzip、日志)会提前写响应头,导致协议升级失败或签名验证不通过。
- 微信支付回调必须用
app.POST,且路径与后台配置的notify_url完全一致(包括是否带尾部斜杠);同时要在 handler 开头加c.Set("skip_csrf", true) - WebSocket 路由不能走任何中间件:必须用
app.Use(func(next buffalo.Handler) buffalo.Handler { return next })绕过,或单独起一个裸http.Server处理/ws - 如果你在
Group()里注册了这类路由,记得先调用group.Use(noopMiddleware)清空该分组中间件栈,而不是指望父级跳过 - Nginx 反代 WebSocket 时,必须显式透传
Upgrade和Connection头,Buffalo 自身不处理这个
真正容易被忽略的是路由注册顺序:Buffalo 匹配路径时按代码书写顺序从上到下,app.GET("/users/:id", ...) 如果写在 app.GET("/users/new", ...) 前面,那么 /users/new 永远不会被匹配到——因为 :id 会先把 new 当作参数值捕获。


















