buffalo generate resource 命令一键生成完整 crud 骨架,包括 handler、模型、迁移、html 模板和 restful 路由,但默认面向服务端渲染;用于 api 时需手动替换 c.render() 为 c.json()、清理 csrf/session 中间件、补 json tag 并调整路由版本。

buffalo generate resource 是 Buffalo 提供的、真正能“一键生成完整 CRUD”的命令,但它生成的内容默认面向服务端渲染(HTML + 模板),不是开箱即用的 JSON API。你得清楚它干了什么、哪些必须改、哪些可以直接删。
运行 buffalo generate resource 后实际生成了什么
执行 buffalo generate resource users name:string email:string 会立刻创建:
-
actions/users.go:含List、Show、Create、Update、Destroy五个 handler(注意:不是Index或New,Buffalo 用的是 Rails 风格命名) -
models/user.go和迁移文件(popORM 结构体 +up/downSQL) -
templates/users/下全套 HTML 模板(index.html、show.html等) - 自动注册 RESTful 路由(
GET /users、POST /users等) - 在
app.go中插入app.Resource("/users", &UsersResource{})
这些加起来确实是“完整 CRUD”,但前提是你要走 MVC 流程——模板渲染、表单提交、Flash 消息、CSRF 校验全包。如果你只写 API,那 templates/ 目录和中间件链就是累赘。
为什么 c.Render() 在 API 场景下会直接 panic
生成的 handler 默认调用 c.Render(200, r.HTML(...)),而 Buffalo 的 Render 会尝试查找并执行对应模板。一旦你删了 templates/users/index.html,再访问 GET /users 就报错:
template: "users/index.html" is undefined
这不是路由没配好,是 c.Render() 强依赖模板存在。API 场景下必须全部替换成 c.JSON():
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
- 把所有
c.Render(...)替换为c.JSON(200, data) - 删掉或注释掉
r.HTML、r.String等模板相关调用 -
List和Show返回结构体切片或单个 struct;Create/Update返回201或200+ 实体;Destroy返回204
中间件链不清理,POST /users 就会 400 或 500
Buffalo 自动生成的中间件包括 session.Middleware、csrf.Middleware、pop.Transaction。它们对 API 是干扰源:
-
csrf.Middleware会拦截所有非 GET 请求,要求 header 带X-CSRF-Token,前端不传就 400 -
session.Middleware会尝试读写 cookie,而 API 通常无状态,且可能跨域 -
pop.Transaction对每个请求开启 DB 事务,哪怕只是GET /users—— 性能浪费,还可能阻塞连接池
清理方式不是删代码,而是改 app.go:
- 找到
app.Use(session.Middleware())这行,注释掉 - 同理注释掉
app.Use(csrf.Middleware()) - 保留
pop.Transaction只在需要事务的 handler 里手动调用(比如Create),而不是全局挂载
别信“跳过模板就能当 API 用”这种说法
有人试过加 --skip-template 参数:buffalo g resource --skip-template users ...,以为能省事。结果发现:
- 路由还是注册成了
/users,不是/api/v1/users,版本控制要自己补中间件 -
actions/users.go里仍保留c.Render()调用,不手动改照样 panic - 模型和迁移照常生成,但
models.User缺少 JSON tag(如json:"name"),返回字段全是大写首字母
所以最稳的路径是:用 generate resource 快速拉出骨架 → 手动替换所有 c.Render → 清理中间件 → 补上 json: tag → 加一层 API 版本中间件。生成器省的是 CRUD 路由和模型结构,不是免配置。










