buffalo 默认不支持开箱即用的 json api,因生成的 resource 基于 html 渲染,需手动替换 c.render 为 c.json、禁用 session/csrf/transaction 中间件,并确保 templates=nil;推荐新建项目时使用 --api 模式。

Buffalo 默认不生成开箱即用的 JSON 接口,buffalo generate resource 产出的是 HTML 渲染骨架,直接用于 API 会报 template: "users/index.html" is undefined、403、404 或 500——不是你代码写错了,是中间件和渲染逻辑根本没为 JSON 设计。
为什么 c.Render() 在 API 场景下必然失败
生成的 handler(如 UsersResource.List)默认调用 c.Render(200, r.Auto(c, users)),而 r.Auto() 会按 Accept 头决定走 HTML 还是 JSON,但前提是模板存在且中间件链兼容。实际中:
- 删了
templates/users/目录 →c.Render()立即 panic:template: "users/index.html" is undefined - 保留模板但前端发
Accept: application/json→r.Auto()尝试调c.JSON(),但中间件仍在运行:CSRF 拦截 POST、Session 读写 cookie 失败、pop.Transaction 强制开 DB 事务 -
Content-Type默认是text/html; charset=utf-8,哪怕返回了 JSON 字符串,前端也收不到正确 MIME 类型
手动修复已生成的 resource(最小改动)
如果你已经跑了 buffalo generate resource users name:string,必须改三处,缺一不可:
- 在
actions/users.go中,把所有c.Render(...)替换为c.JSON(...),例如:c.Render(200, r.Auto(c, users))→c.JSON(200, users)c.Render(422, r.Auto(c, errors))→c.JSON(422, errors) - 在
app.go中注释或删除这三行:app.Use(session.Middleware)app.Use(csrf.New())app.Use(pop.Transaction) - 确认
app.Templates = nil已设置(否则r.Auto()仍会尝试加载模板)
更推荐:从 --api 模式新建项目
避免后期清理陷阱,新项目直接用 API 模式初始化:
- 运行
buffalo new myapi --api --skip-yarn,它不会创建templates/、assets/、Webpack 配置 - 删掉
models/(除非真要用 pop),改用database/sql或gorm直连 - 路由不用
app.Resource(),显式注册:app.GET("/api/v1/users", UsersList)app.POST("/api/v1/users", UsersCreate) - handler 内直接用
json.NewEncoder(c.Response()).Encode(data),完全绕过 Buffalo 的Render层,可控性最高
真正容易被忽略的点是中间件顺序和 Content-Type 的隐式 fallback:即使你写了 c.JSON(200, data),若前面有未清理的 session.Middleware,它可能在写 header 前就 panic;而 r.Auto() 的自动格式推断在前后端分离项目里几乎总是反直觉的——别依赖它。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











