Buffalo中读取路由参数用c.Param("key"),读取查询参数必须用c.Request().URL.Query().Get("key")并手动设默认值,不可混用;推荐封装QueryParam()辅助函数简化处理。

Buffalo框架里用c.Param()还是c.Param("key")?
不是所有参数都叫id,也不是所有请求都带?page=1&size=20。Buffalo的c.Param()只取路由路径里的命名参数(比如/users/:id中的id),它对query string完全无效。想拿?sort=name&dir=asc,得换方法。
正确读取Query参数并设默认值:用c.Param("key")会报错,该用c.Request().URL.Query().Get()
Buffalo控制器的c对象封装了*http.Request,但没提供类似QueryParam()这种便捷方法。直接调c.Param("page")会返回空字符串甚至panic(如果key不存在且没做nil检查)。稳妥做法是穿透到底层URL.Query():
page := c.Request().URL.Query().Get("page")
if page == "" {
page = "1"
}
size := c.Request().URL.Query().Get("size")
if size == "" {
size = "10"
}
注意:Get()返回string,不解析类型;要转int得自己用strconv.Atoi(),失败时记得 fallback。
更简洁的写法:封装成QueryParam()辅助函数
重复写Get() + if == ""太啰嗦,建议在actions/render.go或app.go里加个工具函数:
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
func QueryParam(c buffalo.Context, key, def string) string {
v := c.Request().URL.Query().Get(key)
if v == "" {
return def
}
return v
}
然后控制器里就能一行搞定:
page := QueryParam(c, "page", "1") size := QueryParam(c, "size", "20") sort := QueryParam(c, "sort", "created_at") dir := QueryParam(c, "dir", "desc")
这个函数不处理类型转换,保持轻量;需要int或bool就再包一层,比如QueryInt(c, "limit", 50)。
别踩坑:ParseForm()不是必须的,但POST表单和GET混用时要注意
URL.Query().Get()本身不依赖ParseForm(),它只解析URL里的?后部分,所以GET请求永远安全。但如果你在POST接口里也想读?foo=bar,就得确保没提前调c.Request().ParseForm()——某些中间件(比如CSRF)可能已触发,而ParseForm()会把query和body合并进Form,导致Query()被清空。保险起见,要么早于所有中间件读Query(),要么坚持用URL.Query()(它绕过Form缓存)。

















