直接选RESTful。博客后台是CRUD密集型场景,HTTP方法语义天然匹配资源操作,如GET /api/articles列表、POST新建、PUT更新、DELETE删除,且Gin框架原生适配RESTful规范,强行套RPC会增加复杂度、降低可调试性。

后台接口该用 RESTful 还是 RPC 风格?
直接选 RESTful。Gin 本身不是为 RPC 设计的,强行套 gRPC 或自定义二进制协议反而增加复杂度、降低可调试性。博客后台本质是 CRUD 密集型场景(文章增删改查、分类管理、评论审核),HTTP 方法语义天然匹配:GET /api/articles 列表,POST /api/articles 新建,PUT /api/articles/123 更新,DELETE /api/articles/123 删除。
容易踩的坑:
- 路径里混入动词,比如
/api/deleteArticle?id=123—— 违反 REST 原则,也难做统一权限拦截 - 所有接口都用
POST+ body 模拟其他方法,导致 Swagger 文档失效、前端无法利用浏览器缓存 - 忽略 HTTP 状态码语义,比如删除不存在的文章返回
200而不是404
路由注册要不要手动写死?
别手写。中小型项目看似简单,但一旦加到 20+ 接口,router.GET(...) 堆砌会迅速失控,尤其涉及版本升级(如 /v1/articles → /v2/articles)或模块拆分(admin / api / webhooks)时,维护成本陡增。
推荐做法:
- 按模块组织路由文件,例如
routes/article.go、routes/category.go - 每个文件导出一个注册函数,如
RegisterArticleRoutes(router *gin.Engine, group string) - 主程序里统一调用:
routes.RegisterArticleRoutes(r, "/api/v1") - 避免在
main.go里直接写router.Group("/admin").Use(authMiddleware).GET(...)—— 中间件绑定和路由逻辑耦合太紧
JWT 认证中间件怎么接进路由链?
必须放在路由分组之前,不能靠 handler 内部手动校验。否则每个接口都要重复解析 token、查用户、判断权限,既冗余又易漏。
正确姿势:
- 定义中间件函数
JWTAuth(),解析 header 中的x-token,验证签名和过期时间,把用户 ID 或角色写入c.Set("userID", uid) - 对需要鉴权的路由分组统一挂载:
authGroup := router.Group("/api/v1").Use(JWTAuth()) - 后续所有子路由自动继承该中间件,无需再单独处理
- 注意:登录接口(
POST /api/v1/login)不能挂这个中间件,否则永远进不去
分页参数怎么设计才不翻车?
别用 ?page=1&size=10 这种裸参数。Gin 的 c.Query 默认返回字符串,不校验类型和范围,前端传 ?page=abc&size=-5 就可能 panic 或查出全表。
稳妥做法:
- 封装一个
ParsePageQuery(c *gin.Context) (int, int, error)函数,内部用strconv.Atoi转换并做边界检查(如 page ≥ 1,size ≤ 100) - 错误时统一返回
400 Bad Request和结构化提示,例如{"code":400,"msg":"invalid page parameter"} - 数据库查询层不要依赖 OFFSET/LIMIT 做深分页(>1000 页性能崩),后台管理场景建议用游标分页(cursor-based),基于主键或时间戳推进
真实项目里,最常被忽略的是错误处理的一致性——同一个分页参数,在文章列表、评论列表、用户列表里应该用同一套校验逻辑,而不是每个 handler 各写一遍。


















