Beego入门需严格遵循项目结构和路由注册规范:项目必须建在$GOPATH/src下,routers/router.go中显式注册路由并空白导入"_myapp/routers",Controller须嵌入beego.Controller且方法名大写动词开头。

beego 入门不是“装完就能跑”,最常卡在项目结构和路由注册这两步。不按约定来,bee run 启动后访问 / 直接 404,连日志都不报错。
项目必须建在 $GOPATH/src 下,否则包全找不到
Beego 的 bee 工具至今仍依赖 GOPATH 路径解析 import,哪怕你有 go.mod,它也只认 $GOPATH/src/myapp/ 这种结构。
- 错误做法:
mkdir myapp && cd myapp && bee new .→main.go里import "myapp/controllers"报cannot find package - 正确做法:先运行
go env GOPATH(比如输出/home/user/go),然后cd /home/user/go/src,再执行bee new myapp - 验证是否成功:生成的目录必须是
$GOPATH/src/myapp/,且main.go中的 import 路径(如"myapp/controllers")能与该位置严格对应
routers/router.go 必须显式注册路由,AutoRouter 不可靠
Beego 不会自动扫描控制器方法,所有路由都得手动写进 routers/router.go 的 init() 函数里。没注册 = 不响应请求。
-
main.go中必须有空白导入:_ "myapp/routers"(注意下划线),否则init()根本不执行,路由零注册 - 注册写法必须是:
beego.Router("/", &controllers.MainController{})—— 注意是&controllers.XxxController{},不是controllers.XxxController{}(类型实例化不能少&) - 如果只是返回字符串,用
beego.Get("/", func(ctx *context.Context) { ctx.WriteString("OK") })更快,但别混用:这种写法不走 Controller 生命周期,c.TplName、c.Data全无效
Controller 结构体必须嵌入 beego.Controller,方法名要大写+动词前缀
Beego 靠反射识别 Controller,不是靠继承或接口。任何偏差都会导致方法被跳过,Get() 一动不动。
- 结构体必须直接嵌入:
type MainController struct { beego.Controller }—— 不能是指针字段、不能是组合字段、不能省略 - 方法名必须首字母大写 + HTTP 动词开头:
Get()、Post()、Delete();get()或HandleGet()都不会被识别 - 文件必须放在
controllers/目录下,包名必须是controllers - 若用
beego.Router("/user/:id", &UserController{}),则Get()方法签名必须是func(c *UserController) Get(),参数不能多也不能少
模板路径和变量名必须严格匹配,TplName 不是写了就生效
c.TplName = "index.tpl" 不等于页面能出来。Beego 对模板路径、字段名、启动方式都有硬性约定,三者缺一不可。
- 模板文件必须存在且路径精确:
views/index.tpl(大小写敏感),若放views/admin/index.tpl,就得写c.TplName = "admin/index.tpl" - 传数据用
c.Data["Website"] = "beego.dev",模板里必须写{{.Website}},不是{{.Data.Website}},也不是{{.data.Website}} - 必须调
beego.Run()—— 如果只写http.ListenAndServe()或漏掉这句,模板引擎根本不会启用,TplName被完全忽略
真正的难点不在语法,而在路径、包名、嵌入方式、init 触发这四者的耦合校验——少一个,整个流程就静默失败。调试时别急着改逻辑,先确认 $GOPATH/src/myapp/ 目录是否存在、main.go 是否空白导入了 routers、controllers/default.go 里结构体是否真的嵌入了 beego.Controller。











