用c.Param()取路径参数需路由明确定义{key},如/app.GET("/users/{id}", h);查询参数用c.Request().URL.Query().Get("key");二者类型均为string,须手动转换校验。

URL路径参数怎么取:用 c.Param(),但必须匹配路由定义
Buffalo 不会自动把 URL 路径里的值塞进变量,c.Param("id") 能拿到值的前提是:路由注册时明确写了这个命名参数。比如 app.GET("/users/{id}", UsersShow),这时 c.Param("id") 才返回字符串 "123";如果写的是 app.GET("/users?id=123", UsersShow),那 c.Param("id") 就是空。
常见错误是路由没带 {id} 却硬写 c.Param("id"),结果始终为空。别猜,先看 config/routes.go 里这行路由是不是真有花括号。
- 路径参数名区分大小写:
{PostID}和{post_id}是两个不同参数 -
c.Param()返回的是string,要转成 int 或 uint 得自己调strconv.Atoi或uuid.Parse - 多个嵌套参数如
/posts/{post_id}/comments/{id},两个都得在路由里声明,才能同时用c.Param("post_id")和c.Param("id")
查询参数(?q=go&page=2)怎么读:用 c.Request().URL.Query().Get()
URL 后面的 ?key=value 部分叫查询参数,Buffalo 不提供类似 c.QueryParam("q") 的快捷方法,得走标准库路径:c.Request().URL.Query().Get("q")。它返回字符串,不存在的 key 返回空字符串,不会 panic。
注意:别在没调 ParseForm() 的前提下误用 c.Request().FormValue()——那是为表单 body 准备的,对查询参数无效。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 要读多个同名参数(如
?tag=go&tag=web),用c.Request().URL.Query()["tag"],返回[]string - 如果参数值含 URL 编码(如空格变
%20),Query().Get()已自动解码,不用再调url.QueryUnescape - 别和表单绑定混用:查询参数不会被
c.Bind()处理,哪怕结构体字段打了schema:"q"标签,也得单独解
嵌套路由的参数怎么透传:靠 Scope() + 手动取值
Buffalo 没有“自动注入父级参数”的机制。比如你注册了 app.Scope("/posts/{post_id}", ...),里面的子路由 handler(如 CommentsResource.Index)并不会自动获得 post_id 字段或关联上下文。你得在每个 handler 开头手动调 c.Param("post_id"),然后自己查数据库、校验权限、拼 SQL 条件。
典型漏掉的点:生成器创建的 CommentsResource 默认查全部评论,不加 Where("post_id = ?", c.Param("post_id")) 就直接返回错的数据。
- 模板里生成嵌套链接时,不能用
commentsPath(),得用postCommentsPath(map[string]interface{}{"post_id": post.ID}) - 表单提交目标 action 也要显式带上
post_id,否则 POST 到/comments会丢失上下文 - Destroy 操作前必须校验该 comment 是否属于当前
post_id,否则存在越权删除风险
参数类型转换和校验容易踩什么坑
Buffalo 不做任何隐式类型转换或校验。你拿到 c.Param("id") 是字符串,Query().Get("page") 也是字符串,全靠你自己转、自己判。最常出问题的是整数解析失败后没处理错误,导致后续用 0 做条件查库,返回意外数据。
- 用
strconv.ParseUint(c.Param("id"), 10, 64)而不是strconv.Atoi,避免负数或溢出时静默截断 - 查询参数如
page必须校验是否 > 0,否则db.Paginate(0, ...)可能崩掉或返回全部记录 - 别在中间件里提前解析并塞进 context(如
c.Set("postID", id)),因为下游 handler 未必需要,还可能被覆盖;按需解析更清晰
路径参数和查询参数本质不同,Buffalo 对它们的处理路径完全分离。想靠一个函数通吃所有参数,只会掉进静默失败的坑。









