用beego开发服务端应用

用beego开发服务端应用

  • 说明
  • Quick Start
    • 安装
    • 创建应用
    • 编译运行
    • 打包发布
    • 代码生成
  • 开发文档
  • 目录结构说明
  • 使用配置文件
  • beego默认参数
  • 路由设置
    • 路由的表述方式
    • 直接设置路由
    • 以注册handler的方式设置路由
    • 自动注册路由
    • 通过注解注册路由
    • 使用namespace管理路由
  • 需要特别注意的NSAfter()
  • 使用数据库
  • 数据库迁移(migration)
  • beego.Controller处理http请求
  • 参考
说明 beego是国内团队开源的golang开发框架,是一个关注度和使用量都比价高的项目。
Quick Start beego快速入门中给出一个很简单的例子。
安装
首先需要安装beego和bee工具:
$ go get -u github.com/astaxie/beego $ go get -u github.com/beego/bee

为了能够直接使用bee命令,需要将$GOPATH/bin添加到$PATH变量中。
创建应用
创建一个名为hello的应用,可以选择web应用,或者api应用:
$ bee new hello//创建一个web应用 $ bee api hello//创建一个api应用

执行结束后,会在当前目录下创建名为hello的目录:
. |____hello | |____conf | | |____app.conf | |____controllers | | |____default.go | |____main.go | |____models | |____routers | | |____router.go | |____static | | |____css | | |____img | | |____js | | | |____reload.min.js | |____tests | | |____default_test.go | |____views | | |____index.tpl

编译运行
进入hello目录中,执行bee run,就会完成编译、运行:
$ cd hello/ $ bee run ______ | ___ \ | |_/ /______ | ___ \ / _ \ / _ \ | |_/ /|__/|__/ \____/\___| \___| v1.9.1 2017/10/23 14:33:05 INFO? 0001 Using 'hello' as 'appname' 2017/10/23 14:33:05 INFO? 0002 Initializing watcher... 2017/10/23 14:33:06 SUCCESS? 0003 Built Successfully! 2017/10/23 14:33:06 INFO? 0004 Restarting 'hello'... 2017/10/23 14:33:06 SUCCESS? 0005 './hello' is running... 2017/10/23 14:33:06 [I] [asm_amd64.s:2197] http server Running on http://:8080

打包发布
项目打包发布:
$ bee pack

代码生成
生成models:
bee generate model user -fields="name:string,age:int"

生成controller:
bee generate controller user

生成view:
bee generate view user

生成文档:
bee generate docs

开发文档 beego开发文档中对beego做了很详细的说明。
用beego开发服务端应用
文章图片

目录结构说明
. |____hello | |____conf<- 配置文件 | | |____app.conf | |____controllers<- 控制器,即http请求的handler | | |____default.go | |____main.go<- main函数 | |____models | |____routers<- 路由,将url关联到controllers | | |____router.go | |____static<- 静态文件 | | |____css | | |____img | | |____js | | | |____reload.min.js | |____tests<- 测试 | | |____default_test.go | |____views<- 页面模版,controller中可以直接渲染对应的tpl文件 | | |____index.tpl

使用配置文件 beego参数配置中讲解如何使用配置文件、如何配置参数。
beego默认解析应用目录下的conf/app.conf文件,配置项可以通过beego.AppConfig.*读取:
beego.AppConfig.String("mysqluser")

beego.Appconfig包含多个方法:
Set(key, val string) error String(key string) string Strings(key string) []string Int(key string) (int, error) Int64(key string) (int64, error) Bool(key string) (bool, error) Float(key string) (float64, error) DefaultString(key string, defaultVal string) string DefaultStrings(key string, defaultVal []string) DefaultInt(key string, defaultVal int) int DefaultInt64(key string, defaultVal int64) int64 DefaultBool(key string, defaultVal bool) bool DefaultFloat(key string, defaultVal float64) float64 DIY(key string) (interface{}, error) GetSection(section string) (map[string]string, error) SaveConfigFile(filename string) error

配置文件中可以配置section,通过runmode指定要使用的section,例如:
appname = beepkg httpaddr = "127.0.0.1" httpport = 9090 runmode ="dev" autorender = false recoverpanic = false viewspath = "myview"[dev] httpport = 8080 [prod] httpport = 8088 [test] httpport = 8888

对于section的配置项,通过下面的方式读取,模式::配置参数名:
beego.AppConfig.String(“dev::mysqluser”)

配置文件中可以使用环境变量:
runmode= "${ProRunMode||dev}" httpport = "${ProPort||9090}"

加载特定的配置文件,可以加载多个配置文件,key不能冲突:
beego.LoadAppConfig("ini", "conf/app2.conf") beego.LoadAppConfig("ini", "conf/app3.conf")

beego默认参数 beego的默认参数全部保存在beego.BConfig中。,可以访问、修改所有的配置信息。
在配置文件中设置的同名的key(不区分大小写)的值会覆盖默认值,例如:
appname = hello httpport = 8080 runmode = dev[dev] AutoRender=false#会覆盖beego.BConfig.WebConfig.AutoRender的默认值[test][prod]

App配置:
beego.BConfig.AppName = "beego" beego.BConfig.RunMode = "dev" beego.BConfig.RouterCaseSensitive = true beego.BConfig.ServerName = "beego" beego.BConfig.RecoverPanic = true beego.BConfig.EnableGzip = false beego.BConfig.MaxMemory = 1 << 26 beego.BConfig.EnableErrorsShow = true beego.BConfig.EnableErrorsRender = true

Web配置:
beego.BConfig.WebConfig.AutoRender = true beego.BConfig.WebConfig.EnableDocs = true beego.BConfig.WebConfig.FlashName = "BEEGO_FLASH" beego.BConfig.WebConfig.FlashSeperator = "BEEGOFLASH" beego.BConfig.WebConfig.DirectoryIndex = false beego.BConfig.StaticDir = static beego.BConfig.WebConfig.StaticExtensionsToGzip = []string{".css", ".js"} beego.BConfig.WebConfig.TemplateLeft=" beego.BConfig.WebConfig.TemplateRight=" beego.BConfig.WebConfig.ViewsPath="views" beego.BConfig.WebConfig.EnableXSRF = false beego.BConfig.WebConfig.XSRFKEY = "beegoxsrf" beego.BConfig.WebConfig.XSRFExpire = 0

监听配置:
beego.BConfig.Listen.Graceful=false beego.BConfig.Listen.ServerTimeOut=0 beego.BConfig.Listen.ListenTCP4 = "tcp4" beego.BConfig.Listen.EnableHTTP = true beego.BConfig.Listen.HTTPAddr = "" beego.BConfig.Listen.HTTPPort = 8080 beego.BConfig.Listen.EnableHTTPS = false beego.BConfig.Listen.HTTPSAddr = "" beego.BConfig.Listen.HTTPSPort = 10443 beego.BConfig.Listen.HTTPSCertFile = "conf/ssl.crt" beego.BConfig.Listen.HTTPSKeyFile = "conf/ssl.key" beego.BConfig.Listen.EnableAdmin = false beego.BConfig.Listen.AdminAddr = "localhost" beego.BConfig.Listen.AdminPort = 8088 beego.BConfig.Listen.EnableFcgi = false beego.BConfig.Listen.EnableStdIo = false

Session配置:
beego.BConfig.WebConfig.Session.SessionOn = false beego.BConfig.WebConfig.Session.SessionProvider = "" beego.BConfig.WebConfig.Session.SessionName = "beegosessionID" beego.BConfig.WebConfig.Session.SessionGCMaxLifetime = 3600 beego.BConfig.WebConfig.SessionProviderConfig beego.BConfig.WebConfig.Session.SessionCookieLifeTime = 3600 beego.BConfig.WebConfig.Session.SessionAutoSetCookie = true beego.BConfig.WebConfig.Session.SessionDomain = ""

Log配置:
beego.BConfig.Log.AccessLogs = false beego.BConfig.Log.FileLineNum = true beego.BConfig.Log.Outputs = map[string]string{"console": ""}

路由设置 beego支持三种路由: 基础路由、正则路由、自动路由。
路由的表述方式
支持用正则的方式书写路由,参考了sinatra的路由实现。
路由规则可以匹配 /api/?:id---->/api/, /api/123 id=123 /api/:id---->/api/123id=123 /api/:id([0-9]+)---->/api/123id=123 /user/:username([\w]+)---->/user/abc username=abc /download/*.*---->/download/file/api.xmlpath=file/api ext=xml /download/ceshi/*---->/download/cechis/file/api.jsonsplat=file/api.json /:id:int---->等同于/:id([0-9]+) /:hi:string---->等同于/:hi([\w]+) /cms_:id([0-9]+).html---->/cms_123.htmlid=123

【用beego开发服务端应用】可以通过*context.Context的Input.Param()方法读取路由中的变量:
ctx.Input.Param(":id")

在Controller中,通过下面的方式获取路由中的变量,this是controller:
this.Ctx.Input.Param(":id") this.Ctx.Input.Param(":username") this.Ctx.Input.Param(":splat") this.Ctx.Input.Param(":path") this.Ctx.Input.Param(":ext")

直接设置路由
routers/router.go中设置,可以使用下面的基础函数直接设置路由:
beego.Get(router, beego.FilterFunc) beego.Post(router, beego.FilterFunc) beego.Put(router, beego.FilterFunc) beego.Head(router, beego.FilterFunc) beego.Options(router, beego.FilterFunc) beego.Delete(router, beego.FilterFunc) beego.Any(router, beego.FilterFunc)

例如:
//响应post /alice beego.Post("/alice",func(ctx *context.Context){ ctx.Output.Body([]byte("bob")) })//响应到/foo的所有http请求 beego.Any("/foo",func(ctx *context.Context){ ctx.Output.Body([]byte("bar")) })

以注册handler的方式设置路由
也可以使用beego.Handler(router, http.Handler)设置路由的handler:
beego.Handler("/rpc", s)

beego.Handler默认是完全匹配,不是前缀匹配。可以自定义http请求方法和处理函数的映射关系:
beego.Router("/api/list",&RestController{},"*:ListFood") beego.Router("/api/create",&RestController{},"post:CreateFood") beego.Router("/api/update",&RestController{},"put:UpdateFood") beego.Router("/api/delete",&RestController{},"delete:DeleteFood")

自定义映射关系的格式为”请求方法:函数名”,请求方法有下面几种:
*: 包含以下所有的函数,优先级低于下面的方法 get: GET 请求 post: POST 请求 put: PUT 请求 delete: DELETE 请求 patch: PATCH 请求 options: OPTIONS 请求 head: HEAD 请求

自动注册路由
另外还有beego.AutoRouter($controllers.ObjectController{}),会自动通过反射为Object中的方法生成路由。
通过注解注册路由
在controller的方法上面加上router注释,router.go中通过beego.Include(&Controller)引入controller的时候会自动注册路由。
例如:
// CMS API type CMSController struct { beego.Controller }func (c *CMSController) URLMapping() { c.Mapping("StaticBlock", c.StaticBlock) c.Mapping("AllBlock", c.AllBlock) }// @router /staticblock/:key [get] func (this *CMSController) StaticBlock() {}// @router /all/:key [get] func (this *CMSController) AllBlock() {}

然后在router.go中:
beego.Include(&CMSController{})

beego会自动进行源码分析,如果是dev模式,会在routers/commentXXX.go文件。
使用namespace管理路由
namespace支持前套,并且可以对包含其中对路由进行前置过滤、条件判断。
namespace接口如下:
NewNamespace(prefix string, funcs …interface{})初始化 namespace 对象 NSCond(cond namespaceCond)支持满足条件才namespace NSBefore(filiterList …FilterFunc) NSAfter(filiterList …FilterFunc) NSInclude(cList …ControllerInterface) NSRouter(rootpath string, c ControllerInterface, mappingMethods …string) NSGet(rootpath string, f FilterFunc) NSPost(rootpath string, f FilterFunc) NSDelete(rootpath string, f FilterFunc) NSPut(rootpath string, f FilterFunc) NSHead(rootpath string, f FilterFunc) NSOptions(rootpath string, f FilterFunc) NSPatch(rootpath string, f FilterFunc) NSAny(rootpath string, f FilterFunc) NSHandler(rootpath string, h http.Handler) NSAutoRouter(c ControllerInterface) NSAutoPrefix(prefix string, c ControllerInterface)

示例:
//初始化 namespace ns := beego.NewNamespace("/v1", beego.NSCond(func(ctx *context.Context) bool { if ctx.Input.Domain() == "api.beego.me" { return true } return false }), beego.NSBefore(auth), beego.NSGet("/notallowed", func(ctx *context.Context) { ctx.Output.Body([]byte("notAllowed")) }), beego.NSRouter("/version", &AdminController{}, "get:ShowAPIVersion"), beego.NSRouter("/changepassword", &UserController{}), beego.NSNamespace("/shop", beego.NSBefore(sentry), beego.NSGet("/:id", func(ctx *context.Context) { ctx.Output.Body([]byte("notAllowed")) }), ), beego.NSNamespace("/cms", beego.NSInclude( &controllers.MainController{}, &controllers.CMSController{}, &controllers.BlockController{}, ), ), ) //注册 namespace beego.AddNamespace(ns)

注册了以下的路由:
GET /v1/notallowed GET /v1/version GET /v1/changepassword POST /v1/changepassword GET /v1/shop/123 GET /v1/cms/ 对应 MainController、CMSController、BlockController 中得注解路由

需要特别注意的NSAfter() NSAfter()注册的filter函数会在请求处理结束的时候被调用,但是要注意在bee 1.9.0中:
beego.NSAfter does not work after controller.ServeJSON

相关的issue:
注解路由无法进入NSBefore controller.ServeJSON should work will with beego.NSAfter
可以用github: study-beego里的的代码试验一下。
使用数据库 beego仿照Digango ORM和SQLAlchemy实现beego ORM,当前支持三个驱动:
MySQL:github.com/go-sql-driver/mysql PostgreSQL:github.com/lib/pq Sqlite3:github.com/mattn/go-sqlite3

beego生成的model文件中,会自动将model注册到orm,例如:
bee generate model user -fields="name:string,age:int"

生成的代码models/user.go中会在init()中注册:
func init() { orm.RegisterModel(new(User)) }

因此只需要手工书写orm初始化的代码,譬如在main.go中:
func init() { orm.RegisterDataBase("default", "mysql", "root:@tcp(127.0.0.1:3306)/mysql?charset=utf8", 30) }

数据库迁移(migration) 数据库迁移功能可以数据库进行升级、回滚操作。
生成迁移文件,user是表名,fields是表结构:
bee generate migration user -driver=mysql -fields="name:string,age:int"

运行后,生成了文件:
|____database | |____migrations | | |____20171024_154037_user.go

在数据库中创建了名为study-beego的数据库后,执行下面的命令:
bee migrate -driver=mysql -conn="root:@tcp(127.0.0.1:3306)/study-beego"

study-beego中的表将会被创建或者更新,并在名为migrations的表中记录更新。
用beego开发服务端应用
文章图片

migrate的子命令refreshrollback执行失败,原因不明。
beego.Controller处理http请求 注意,在1.9.0中,需要在配置中设置copyrequestbody=true以后,c.Ctx.Input.RequestBody中才有数据。
func (c *UserController) Post() { var v models.User json.Unmarshal(c.Ctx.Input.RequestBody, &v) fmt.Println(v) if _, err := models.AddUser(&v); err == nil { c.Ctx.Output.SetStatus(201) c.Data["json"] = v } else { c.Data["json"] = err.Error() } c.ServeJSON() }

转载于:https://www.cnblogs.com/zhangboyu/p/7760693.html

    推荐阅读