必须统一使用 /api 作为所有后端接口的前缀,版本号置于子路径(如 /api/v1/users),确保前端请求封装、代理配置和 Nginx 重写规则统一可维护;路由须按业务模块拆分并用 Group() 隔离,中间件按作用域精准注册,静态资源与 API 物理隔离,错误响应格式全局统一。

路由前缀统一用 /api,别混用 /v1、/backend 这类随意命名
前后端分离项目里,前端调用后端的路径必须稳定、可预测。如果路由前缀五花八门(比如有的接口是 /user,有的是 /v2/tasks,还有的是 /svc/status),前端团队没法写通用请求封装,代理配置也容易出错。
推荐做法:所有 API 路由强制走 /api 前缀,版本号作为子路径,例如:
/api/v1/users/api/v2/tasks/api/v1/auth/login
这样 Nginx 或 Vercel 的 rewrite 规则能统一匹配 /api/** 并转发到后端,前端 Axios 默认 baseURL 也只需设为 /api,不用在每个请求里拼前缀。
r.Group() 必须按业务模块拆分,别把全部路由塞进一个 router.go
500 行起步的单文件路由是维护噩梦。Gin 的 Group() 不只是语法糖,它是模块隔离的第一道防线。
正确组织方式:
- 每个业务模块(如 user、task、auth)各自一个
router/user.go、router/task.go - 每个文件导出一个注册函数,例如
func RegisterUserRoutes(r *gin.RouterGroup) - 总路由入口(如
router/router.go)只负责调用这些函数:func SetupRouter(r *gin.Engine) { api := r.Group("/api") v1 := api.Group("/v1") RegisterUserRoutes(v1) RegisterTaskRoutes(v1) RegisterAuthRoutes(v1) }
好处很明显:新增模块不改老代码;单元测试时可以只加载某几个路由组;上线灰度也能按模块开关。
中间件注册位置决定作用域,r.Use() 和 group.Use() 完全不是一回事
Gin 的中间件作用范围极易混淆。全局中间件(如日志、panic 捕获)必须用 r.Use();而鉴权、权限校验这类只对 API 生效的中间件,必须挂到 api.Group("/v1").Use() 下。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
常见错误:
- 把 JWT 鉴权中间件写成
r.Use(AuthMiddleware)→ 导致/healthz、/metrics等运维接口也被拦住 - 在
v1.Group("/users")内重复调用.Use(AuthMiddleware)→ 同一请求被校验多次,且无法共享中间件间的数据(比如从 token 解析出的userID) - 漏掉
OPTIONS方法放行 → 前端发带Authorizationheader 的请求时,预检失败静默卡住
正确写法示例:
v1 := api.Group("/v1")
v1.Use(AuthMiddleware, LoggerMiddleware) // 所有 /api/v1/xxx 都走这两层
{
v1.GET("/users", listUsers)
v1.POST("/tasks", createTask)
}
静态资源和 API 路由必须物理隔离,禁止用 r.StaticFS() 挂整个 dist/
前后端分离 ≠ 把前端打包文件扔进 Go 二进制一起 serve。直接用 r.StaticFS("/static", http.Dir("./dist")) 有两大风险:
- 默认开启目录遍历,
/static/..%2f..%2f/etc/passwd可读敏感文件 - 所有以
/static开头的请求都被拦截,导致/static/api/v1/users这种误配路径返回 404 而非交由 API 路由处理
生产环境唯一安全做法:让 Nginx 或 CDN 处理静态资源,Gin 只管 /api/**;若必须内嵌(如 demo 环境),用 http.FileServer + http.StripPrefix + 显式路径白名单:
fs := http.FileServer(http.Dir("./dist"))
r.NoRoute(func(c *gin.Context) {
if strings.HasPrefix(c.Request.URL.Path, "/api/") {
c.Next() // 交给 API 路由
return
}
fs.ServeHTTP(c.Writer, c.Request)
})
这样既防穿越,又避免路由冲突。
最常被忽略的一点:API 路由的错误响应格式必须统一。不要有的接口返回 {"error": "xxx"},有的返回 {"code": 40001, "msg": "xxx"},前端异常处理会疯掉。这个细节比路由结构本身更影响协作效率。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










