最近项目用到beego,花了半天结合官方文档写了几个demo看懂了套路,对于我这个没有什么web开发经验的也很容易上手。
1 restful 风格
beego.Post("/test",controllers.Test)
beego.Get("/home",func(ctx* context.Context){
ctx.Output.Body([]byte("hello beego "))
})
这种类似于c里面注册一个回调函数,http get/post method时就执行相应注册函数。
beego.Router("/main", &controllers.MainController{})
这种类似于c++里面注册一个子类,子类实现Get 、Post 、Put、Delete 接口。但是这里get请求对应Get方法,post请求对应Post方法,为了更加灵活,于是有自定义路由函数
beego.Router("/main", &controllers.MainController{},"get:Main")
beego.Router通过第三个参数指定http method执行 控制器中相关方法。
2 任意路由
beego.Any("/handler",controllers.Handler)
接口:func Any(rootpath string, f FilterFunc) ,只要匹配到rootpath,不管http 什么method,都匹配 f 注册函数,更加灵活通用。
3 自动匹配路由
//router.go 中路由控制器注册
beego.AutoRouter(&controllers.UserController{})
// 控制器UserController 中方法
func (c *UserController) Login() {
c.Ctx.Output.Body([]byte("login success"))
}
func (c *UserController) Logout() {
c.Ctx.Output.Body([]byte("logout success"))
}
对于类似 /user/login /user/logout 请求就能执行控制器中相关方法。相比restful 控制器中Get Post风格,这种路由中的url直接对应控制器中的方法更直接明了。
4 命名空间
ns:=beego.NewNamespace("/api",
beego.NSNamespace("/user",
beego.NSRouter("/login",&controllers.UserController{},"*:Login"),
beego.NSRouter("/logout",&controllers.UserController{},"*:Logout"),
),
beego.NSNamespace("/topic",
beego.NSBefore(controllers.Auth),
beego.NSRouter("/create", &controllers.TopicController{}),
beego.NSRouter("/delete", &controllers.TopicController{}),
),
)
beego.AddNamespace(ns)
命名空间可以将同一类路由置于相同空间下,比如这里第一级namespaec是api ,第二级是user和topic,
beego.NSBefore 在访问api其他namespaec时都会先执行这里的注册函数,比如在访问其他接口前可以做一些登录认证校验。
5 注解路由
这种路由书写起来有些复杂,前面路由完全够用,不过是一种语法糖。
//router.go 中包含控制器
beego.Include(&controllers.NoteController{})
//控制器
type NoteController struct{
beego.Controller
}
func (c *NoteController) URLMapping() {
c.Mapping("Note", c.Note)
}
// @router /note [get]
func (c* NoteController)Note(){
c.Ctx.WriteString("note")
}
看这里注解方式 @routet + 路由(/note)+method(get) 等同
beego.Router("/note ", &controllers.NoteController {}, “get:Note”),明显这种方式更简单。
在使用session 前 配置文件中需要设置sessionon = true,在登录接口保存session
func (c *UserController) Login() {
id:=c.GetString(":id")
v := c.GetSession("userId")
if v == nil {
logs.Info("nil")
c.SetSession("userId", id)
c.TplName = "index.tpl"
} else {
c.Ctx.WriteString("login success")
}
}
于是结合前面路由beego.NSBefore(controllers.Auth),每次访问topic时都可以检测用户session是否存在,如果不存在,可以要求用户登录。
func Auth(ctx* context.Context){
val, ok := ctx.Input.Session("userId").(string)
logs.Info(ok,val)
if !ok && ctx.Request.RequestURI != "/api/user/login" {
logs.Info("redirect")
ctx.Redirect(302, "/api/user/login")
}
}
session默认是保存在内存中,可以配置保存到file redis mysql等。
在配置文件中加上
SessionProvider=file
SessionProviderConfig =./tmp
保存到文件,服务器重启后浏览器访问还是用之前session。
type User struct {
Id int `valid:"Required"`
Name string `valid:"Required;Match(/^Bee.*/)"` // Name 不能为空并且以 Bee 开头
Age int `valid:"Range(1, 140)"` // 1 <= Age <= 140,超出此范围即为不合法
Email string `valid:"Email; MaxSize(100)"` // Email 字段需要符合邮箱格式,并且最大长度不能大于 100 个字符
Mobile string `valid:"Mobile"` // Mobile 必须为正确的手机号
IP string `valid:"IP"` // IP 必须为一个正确的 IPv4 地址
}
// 如果你的 struct 实现了接口 validation.ValidFormer
// 当 StructTag 中的测试都成功时,将会执行 Valid 函数进行自定义验证
func (u *User) Valid(v *validation.Validation) {
if strings.Index(u.Name, "admin") != -1 {
// 通过 SetError 设置 Name 的错误信息,HasErrors 将会返回 true
v.SetError("Name", "名称里不能含有 admin")
}
}
func (c *UserController) Register(){
var user User
if err:=json.Unmarshal(c.Ctx.Input.RequestBody, &user);err!=nil{
logs.Error(" Unmarshal fail:",err)
return
}
valid := validation.Validation{}
b, err := valid.Valid(&user)
if err != nil {
logs.Error(err)
c.Ctx.WriteString(err.Error())
return
// handle error
}
if !b {
// validation does not pass
// blabla...
var msg string
for _, err := range valid.Errors {
msg+=fmt.Sprintf("%s %s %s\n",err.Key,err.Message)
}
c.Ctx.WriteString(msg)
}else{
c.Ctx.WriteString("register success")
}
}
这里有个注册函数,服务端需要校验数据合法性,比如是否为空,是否合邮件规则等。beego/validation模块相当方便。
自带orm不太好用,直接用go-sql-driver/mysql,原生sql写起来更得心应手。
beego虽然模块多,掌握这几个模块就可以开始写代码了,这种web框架学习起来还是挺容易的。
参考: