接口路径需匹配小程序wx.request的baseURL+path拼接逻辑,推荐统一小写连字符Controller名、显式注册路由、加版本前缀;用BaseController的Prepare方法统一鉴权;必须显式调用ServeJSON返回JSON;文件上传须用SaveToFile而非RequestBody解析。

接口路径命名要匹配小程序端 wx.request 的 baseURL + path 拼接逻辑
微信小程序调用后端接口时,wx.request 的 url 是由开发者在 app.js 或请求封装里配置的 baseURL(比如 "https://api.example.com")和具体接口的 path(比如 "/v1/user/login")拼出来的。Beego 默认路由是基于 Controller 方法名自动映射的,但容易忽略大小写和斜杠规则——UserController.Login 默认注册为 /user/login,而 User.Login 会变成 /user/login(小写),但若 Controller 名含大驼峰(如 WxMiniProgramController),方法 GetUserInfo 会被映射为 /wxminiprogram/getuserinfo,这不是你想要的语义化路径。
实操建议:
- 统一用小写字母 + 连字符风格的 Controller 名,比如
usercontroller.go,其中UserController结构体,避免驼峰 Controller 名触发非预期路由 - 显式注册路由,不要依赖 auto-router:在
router.go中写beego.Router("/v1/user/info", &controllers.UserController{}, "get:GetInfo") - 所有 API 路径加版本前缀(如
/v1/),后续兼容升级不破坏小程序端代码 - 小程序端
baseURL建议直接配成"https://api.example.com/v1",后端路由就从/user/info开始写,减少拼接歧义
Beego 的 Prepare 方法适合统一做小程序登录态校验
微信小程序每次请求都带 code 或 token(通常放在 header Authorization: Bearer xxx),你需要在每个需要鉴权的接口开头校验。如果每个 Get/Post 方法里都重复写解析 token、查 Redis、塞用户 ID 到 context,不仅冗余,还容易漏掉或校验逻辑不一致。
Beego 的 Prepare() 是 Controller 生命周期第一个执行的方法,天然适合放公共前置逻辑:
- 在
controllers/base.go定义BaseController,内嵌beego.Controller,重写Prepare() - 从
this.Ctx.Input.Header("Authorization")提取 token,用gtoken.GfTokenManager.GetTokenData(token)解析(注意:gtoken 默认用gcache,生产必须切到redis,否则重启丢 session) - 校验通过后,把用户 ID 存进
this.Data["uid"] = uid,后续方法可直接用;失败则调this.Abort("401") - 让所有业务 Controller 继承
BaseController,无需再手动校验
注意:Prepare 不会跳过 Get 等方法——它只是前置,不是拦截器;若需跳过某些接口(如 /v1/auth/login),得在 Prepare 里判断 this.Ctx.Input.URLPath() 跳过。
返回 JSON 格式必须禁用 Beego 的自动模板渲染
Beego 默认开启模板引擎,当 Controller 方法执行完没显式调用 this.ServeJSON() 时,它会尝试找同名模板(如 login.tpl),导致返回 404 或 HTML 内容,小程序端解析 JSON.parse 直接报错。
公众号运营|微信公众号|公众号一条龙|公众号全流程|自媒体运营|微信自动化|内容流水线|AIGC 工作流 — 公众号一条龙运营总控入口,覆盖选题→撰稿→审稿→排版→配图→发布等8个子技能,单条指令即可完成从零到上架的完整图文。面向公众号编辑、自媒体等用户。
常见错误现象:wx.request 成功回调里 res.data 是一串 HTML 字符串,控制台打印 Unexpected token < in JSON at position 0。
解决方式只有两个:
- 所有 API 方法末尾必须显式调用
this.ServeJSON()(推荐) - 或全局关闭模板:
beego.BConfig.WebConfig.AutoRender = false,然后每个方法自己json.Marshal+this.Ctx.Output.Body()(不推荐,冗余)
另外,ServeJSON 默认带 Content-Type: application/json; charset=utf-8,但若小程序端用了旧版基础库(2.20.0 以下),部分安卓机型对 charset 敏感,可加一行 this.Ctx.Output.Header("Content-Type", "application/json") 强制清除 charset。
文件上传接口要用 this.SaveToFile,别碰 this.Ctx.Input.RequestBody
微信小程序上传文件走的是 wx.uploadFile,它发的是 multipart/form-data 请求,不是 JSON body。如果你在 Beego 里误用 json.Unmarshal(this.Ctx.Input.RequestBody, &req),会得到空结构体或 panic,因为 RequestBody 是二进制边界数据,不是 JSON 字符串。
正确做法是用 Beego 封装好的文件处理:
- 前端
wx.uploadFile的name参数(如"file")要和后端this.SaveToFile("file", "./uploads/xxx.pdf")的第一个参数严格一致 - 先调
this.Ctx.Input.ParseMultipartForm(32 (限制最大 32MB),否则 <code>SaveToFile会失败 - 上传后记得校验
file.Header.Get("Content-Type"),比如 PDF 应为"application/pdf",别只信后缀名 - 临时文件路径由 Beego 自动分配,
SaveToFile会把它移到目标位置;不要试图读RequestBody或自己解析 multipart
这个点特别容易被绕进去——看到「上传」就本能想 parse body,但微信小程序的文件上传机制决定了它必须走 form-data 分流处理,和普通 JSON 接口完全两套逻辑。


















