本文主要分享GO语言常用的web框架:Beego框架,简单分享如何快速入门Beego
Beego框架
Beego框架的简介
Beego框架是一款开源的由国人开发的全栈式的Web框架,它采用了MVC架构,支持自动化路由、ORM、Session、日志、缓存等功能,并提供了丰富的工具和库,适合快速构建Web应用。
Beego 是一个 RESTful HTTP 框架,用于快速开发 Go 语言企业应用程序,例如 RESTful API、Web 应用程序和后端服务。它集成了 Go 语言特定的功能,例如接口和结构嵌入。
Beego具有以下优点:
功能全面:Beego提供了ORM、Session、Cache等多种功能的支持,可以方便地进行Web开发。
简单易用:API设计简单明了,新手通过文档也是能快速入手的,支持RESTful API,使得构建Web服务变得更加简单和高效。
易于扩展:Beego支持插件机制,可以方便地进行扩展和定制。
缺点:
Beego的性能相对较低,不适合高并发场景。
Beego的代码结构较为复杂,虽然有点文档,但是对于他的功能来说不够学习成本较高。
框架庞大,依赖多,不如Gin轻便
社区生态比较小,不如其他web框架,遇到问题需要自己花时间想办法
Beego框架的安装
// 安装Beego框架go get -u github.com/astaxie/beego//安装Beego工具:
go get -u github.com/beego/beego get -u github.com/beego/bee/v2go install github.com/beego/bee/v2@master
安装完成bee可执行性文件默认放在$GOPATH/bin
里面,所以需要把 $GOPATH/bin
添加到环境变量中
此处贴上如何配置环境变量
$env:GOPROXY = "https://goproxy.io,direct" $env:GOPATH = "你的用水来存放项目的工作目录路径" $env:GOROOT = "你安装的GO目录路径看" # 注意以上方法只对于当前会话有效,so,如果你想永久设置可以使用以下命令 #(注意必须在管理员命令下运行) [Environment]::SetEnvironmentVariable("GOPROXY", "https://goproxy.io,direct", "Machine") # "Machine":表示这个环境变量将应用于整个系统,所有用户都可以访问它。设置这样的环境变量通常需要管理员权限。 #"User":表示这个环境变量将只应用于当前用户。设置这样的环境变量通常不需要管理员权限。 #"Process":表示这个环境变量将只应用于当前进程。这对于临时修改当前进程的环境变量很有用,但不会影响其他进程或系统的环境变量。
检查是否安装成功shell输入bee命令
024/03/27 09:19:50.430 [D] init global config instance failed. If you do not use this, just ignore it. open conf/app.conf: The system cannot find the path specified.
2024/03/27 09:19:50 INFO ▶ 0001 Getting bee latest version...
2024/03/27 09:19:51 INFO ▶ 0002 Your bee are up to date
Bee is a Fast and Flexible tool for managing your Beego Web Application.You are using bee for beego v2.x. If you are working on beego v1.x, please downgrade version to bee v1.12.0USAGEbee command [arguments]AVAILABLE COMMANDSdev Commands which used to help to develop beego and beeupdate Update Beeversion Prints the current Bee versionbale Transforms non-Go files to Go source filesfix Fixes your application by making it compatible with newer versions of Beegodockerize Generates a Dockerfile and docker-compose.yaml for your Beego applicationmigrate Runs database migrationsnew Creates a Beego applicationpack Compresses a Beego application into a single filers Run customized scriptsserver serving static content over HTTP on portrun Run the application by starting a local development serverpro Source code generatorapi Creates a Beego API applicationgenerate Source code generatorhprose Creates an RPC application based on Hprose and Beego frameworksdlv Start a debugging session using DelveUse bee help [command] for more information about a command.
这里简单介绍一下bee常用的命令
1、new
命令是新建一个 Web 项目,我们在命令行下执行 bee new <项目名>
就可以创建一个新的项目。但是注意该命令必须在 $GOPATH/src
下执行。
2、api
命令用来开发api应用的,和web应用相比少了少了 static 和 views 目录
api命令快而已自动连接数据库创建相关model和controller
3、run
命令用于快速构建运行项目,通过fsnotify监控文件系统监控beego项目,在开发项目的时候不用频繁的去编译和运行项目,他会自动编译和运行,相当方便
4、pack
命令用来打包项目,打包成zip包,格式.tar.gz
5、generate
命令就来自动生成代码的,加快开发步骤,如:
bee generate scaffold [scaffoldname] [-fields=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"]The generate scaffold command will do a number of things for you.-fields: a list of table fields. Format: field:type, ...-driver: [mysql | postgres | sqlite], the default is mysql-conn: the connection string used by the driver, the default is root:@tcp(127.0.0.1:3306)/testexample: bee generate scaffold post -fields="title:string,body:text"bee generate model [modelname] [-fields=""]generate RESTful model based on fields-fields: a list of table fields. Format: field:type, ...bee generate controller [controllerfile]generate RESTful controllersbee generate view [viewpath]generate CRUD view in viewpathbee generate migration [migrationfile] [-fields=""]generate migration file for making database schema update-fields: a list of table fields. Format: field:type, ...bee generate docsgenerate swagger doc filebee generate test [routerfile]generate testcasebee generate appcode [-tables=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"] [-level=3]generate appcode based on an existing database-tables: a list of table names separated by ',', default is empty, indicating all tables-driver: [mysql | postgres | sqlite], the default is mysql-conn: the connection string used by the driver.default for mysql: root:@tcp(127.0.0.1:3306)/testdefault for postgres: postgres://postgres:postgres@127.0.0.1:5432/postgres-level: [1 | 2 | 3], 1 = models; 2 = models,controllers; 3 = models,controllers,router
6、migrate
命令,数据库迁移命令,常用的有bee migrate,把未完成的迁移的迁移了,rollback 回滚最后一次迁移、reset回滚所有迁移,数据库恢复到迁移前的状态。refresh会回滚所有迁移并且重新迁移
7、dockerize
命令可以生成一个dockerfile来容器化应用
所有命令可以加上help查看详细说明:bee help dockkerize
项目初始化搭建框架
创建新项目在src目录下输入命令
bee new myproject
最后生成的目录结构如下
然后运行bee run
命令,成功启动
beego的MVC架构
controller
beego的配置文件
beego 目前支持 INI、XML、JSON、YAML 格式的配置文件解析,但是默认采用了 INI 格式解析,用户可以通过简单的配置就可以获得很大的灵活性。
appname = myproject
httpaddr = "127.0.0.1"
httpport = 8080
runmode = dev
# 这设置了应用的运行模式。"dev" 通常代表开发模式,这种模式可能提供更详细的日志输出,以及更容易的错误调试。
autorender = false
# 这决定了是否自动渲染模板。当设置为 false 时,你需要手动调用渲染函数来渲染模板。
recoverpanic = false
# 当 Go 代码发生 panic 时,是否尝试恢复它。如果设置为 true,Beego 会尝试捕获 panic 并返回 500 错误。在某些情况下,这可以防止应用崩溃,但也可能隐藏某些严重的错误。
viewspath = "views"
# 这设置了视图文件的路径,即模板文件的存储位置。这里,模板文件被放置在 views 目录中。# 在配置文件里面支持 section,可以有不同的 Runmode 的配置,默认优先读取 runmode 下的配置信息
[dev]
httpport = 8080
[prod]
httpport = 8088
[test]
httpport = 8888
多个APP配置文件
INI 格式配置支持 include
方式,引用多个配置文件,例如下面的两个配置文件效果同上:
app.conf
appname = myproject
httpaddr = "127.0.0.1"
httpport = 9090include "app2.conf"
app2.conf
runmode ="dev"
autorender = false
recoverpanic = false
viewspath = "myview"[dev]
httpport = 8080
[prod]
httpport = 8088
[test]
httpport = 8888
配置文件解析支持从环境变量中获取配置项,配置项格式:${环境变量}
。例如下面的配置中优先使用环境变量中配置的 runmode 和 httpport,如果有配置环境变量 ProRunMode 则优先使用该环境变量值。如果不存在或者为空,则使用 "dev" 作为 runmode。
runmode = "${ProRunMode||dev}"
httpport = "${ProPort||9090}"
更多配置参数大家可以参考官网
beego的路由设置
1、基础路由
beego从1.2开始支持基本的RESTful函数式路由,大多定义在royters/router.go
文件中。最简单的 beego 路由由 URI 和闭包函数组成。
package routersimport ("github.com/astaxie/beego"
)func init() {beego.Get("/", func(ctx *context.Context) {ctx.Output.Body([]byte("Hello, world!")
)})
}
所有支持的基础路由如下:
但是这种路由设置方式不利于代码组织和复用,也不符合beego框架的推荐时间
所以我们一般推荐使用RESTful形式,也就是将路由映射到控制器的方法
2、RESTful Controller 路由
2.1 固定路由
固定路由就是全匹配的路由
在controls/defualt.go
中设置控制器
ppackage controllersimport (beego "github.com/beego/beego/v2/server/web"
)type MainController struct {beego.Controller
}func (c *MainController) Get() {c.Ctx.WriteString("Hello, world!")
}
然后在royters/router.go
设置路由
package routersimport (beego "github.com/beego/beego/v2/server/web""myproject/controllers"
)func init() {beego.Router("/", &controllers.MainController{})}
如上所示的路由就是我们最常用的路由方式,一个固定的路由,一个控制器,然后根据用户请求方法不同请求控制器中对应的方法,典型的 RESTful 方式。
2.2 正则路由
为了用户更加方便的路由设置,beego 参考了 sinatra 的路由实现,支持多种方式的路由:
beego.Router("/api/?:id", &controllers.RController{})
默认匹配 //例如对于URL"/api/123"可以匹配成功,此时变量":id"值为"123"
beego.Router("/api/:id", &controllers.RController{})
默认匹配 //例如对于URL"/api/123"可以匹配成功,此时变量":id"值为"123",但URL"/api/"匹配失败
beego.Router("/api/:id([0-9]+)", &controllers.RController{})
自定义正则匹配 //例如对于URL"/api/123"可以匹配成功,此时变量":id"值为"123"
beego.Router("/user/:username([\w]+)", &controllers.RController{})
正则字符串匹配 //例如对于URL"/user/astaxie"可以匹配成功,此时变量":username"值为"astaxie"
beego.Router("/download/.", &controllers.RController{})
*匹配方式 //例如对于URL"/download/file/api.xml"可以匹配成功,此时变量":path"值为"file/api", ":ext"值为"xml"
beego.Router("/download/ceshi/*", &controllers.RController{})
*全匹配方式 //例如对于URL"/download/ceshi/file/api.json"可以匹配成功,此时变量":splat"值为"file/api.json"
beego.Router("/:id:int", &controllers.RController{})
int 类型设置方式,匹配 :id为int 类型,框架帮你实现了正则 ([0-9]+)
beego.Router("/:hi:string", &controllers.RController{})
string 类型设置方式,匹配 :hi 为 string 类型。框架帮你实现了正则 ([\w]+)
beego.Router("/cms_:id([0-9]+).html", &controllers.CmsController{})
带有前缀的自定义正则 //匹配 :id 为正则类型。匹配 cms_123.html 这样的 url :id = 123
2.3 自定义路由
前面的路由都是通过特定http请求来执行特定函数,比如GET请求执行GET函数,但是如果你想自定义函数名,则使用如下方式
在controls/defualt.go
中设置控制器
type ListController struct {beego.Controller
}func (c *ListController) GetAllBooks() {c.Ctx.WriteString("这是书籍列表")}
func (c *ListController) AddBooks() {c.Ctx.WriteString("添加书籍")
}
籍")
}
royters/router.go
设置路由
func init() {//beego.Router("/", &controllers.MainController{})beego.Router("/list", &controllers.ListController{}, "Get:GetAllBooks")beego.Router("/add", &controllers.ListController{}, "*:AddBooks")beego.Router("/simple", &controllers.ListController{}, "Get,Post:GetAllBooks")beego.Router("/simple1", &controllers.ListController{},"Get:GetAllBooks;Post:AddBooks")beego.Router("simple3", &controllers.ListController{},"*:GetAllBooks;Post:AddBooks")
}
beego.Router("/",&IndexController{},"*:Index")
使用第三个参数,第三个参数就是用来设置对应 method 到函数名,定义如下
*
表示任意的 method 都执行该函数使用 httpmethod:funcname 格式来展示
多个不同的格式使用
;
分割多个 method 对应同一个 funcname,method 之间通过
,
来分割
示例结果
但是当同时存在 * 和对应的 HTTP Method,那么优先执行 HTTP Method 的方法,例如上面代码的路由/simple3
如果你自定义了函数,那么就不会再执行默认的Post函数
2.3 注解路由
注解路由简单的说就是在控制器的函数上方添加路由和请求方式,然后在路由设置中include控制器,beego就会自动解析路由,但是这是2.0.2版本之前,之后beego删除自动生成注解路由的功能需要手动生成,因此最新版本设置注解路由如下
package controllersimport (beego "github.com/beego/beego/v2/server/web"
)type ListController struct {beego.Controller
}func (c *ListController) URLMapping() {c.Mapping("GetAllBooks", c.GetAllBooks)c.Mapping("AddBooks", c.AddBooks)
}// @router /list [get]
func (c *ListController) GetAllBooks() {c.Ctx.WriteString("这是书籍列表")}// @router /add [post]
func (c *ListController) AddBooks() {c.Ctx.WriteString("添加书籍")
}
package routersimport (beego "github.com/beego/beego/v2/server/web""myproject/controllers"
)func init() {beego.Include(&controllers.ListController{})}
然后在自己项目目录终端运行以下命令
bee generate routers [-ctrlDir=/path/to/controller/directory] [-routersFile=/path/to/routers/file.go] [-routersPkg=myPackage]-ctrlDir: the directory contains controllers definition. Bee scans this directory and its subdirectory to generate routers info-routersFile: output file. All generated routers info will be output into this file.If file not found, Bee create new one, or Bee truncates it.The default value is "routers/commentRouters.go"-routersPkg: package declaration.The default value is "routers".When you pass routersFile parameter, youd better pass this parameter
最终会根据你的控制器在routers目录下生成一个注解路由的文件(如果你没有设置最终输出文件采用默认的话),然后运营beego,注解路由才生效。
runmode=dev
2.4 命名空间(namespace)
命名空间可以对路由进行分类管理,便于维护
以下是一个简单的示例
package routersimport (beego "github.com/beego/beego/v2/server/web"beecontext "github.com/beego/beego/v2/server/web/context""myproject/controllers"
)func init() {var ns = beego.NewNamespace("/api",beego.NSCond(func(ctx *beecontext.Context) bool {if ua := ctx.Input.UserAgent(); ua != "" {return true}return false}),beego.NSNamespace("/user",// /api/user/searchbeego.NSRouter("/search", &controllers.UserControllers{}, "Get:SearchUser"),// /api/user/addbeego.NSRouter("/add", &controllers.UserControllers{}, "Get:AddUser"),// /api/user/:id/detailbeego.NSRouter("/:id/detail", &controllers.UserControllers{}, "Get:Detail"),// /api/user/:id/deletebeego.NSRouter("/:id/delete", &controllers.UserControllers{}, "Get:DeleteUser"),),)beego.AddNamespace(ns)
}
namespace 的接口如下:
NewNamespace(prefix string, funcs ...interface{})
初始化 namespace 对象,下面这些函数都是 namespace 对象的方法,但是强烈推荐使用 NS 开头的相应函数注册,因为这样更容易通过 gofmt 工具看得更清楚路由的级别关系
NSCond(cond namespaceCond)
支持满足条件的就执行该 namespace, 不满足就不执行
NSBefore(filiterList ...FilterFunc)
NSAfter(filiterList ...FilterFunc)
上面分别对应 beforeRouter 和 FinishRouter 两个过滤器,可以同时注册多个过滤器
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)
上面这些都是设置路由的函数,详细的使用和上面 beego 的对应函数是一样的
NSNamespace(prefix string, params ...innnerNamespace)
beego请求数据处理
1、直接一个个的获取,一般用户通过请求传递的参数,beego会自动解析,我们通过以下方式获取,前面已经有了一个例子
GetString(key string) string
GetStrings(key string) []string
GetInt(key string) (int64, error)
GetBool(key string) (bool, error)
GetFloat(key string) (float64, error)
func (this *MainController) Post() {jsoninfo := this.GetString("jsoninfo")if jsoninfo == "" {this.Ctx.WriteString("jsoninfo is empty")return}
}
其他类型如int类型
func (this *MainController) Post() {id := this.Input().Get("id")intid, err := strconv.Atoi(id)
}
2、直接解析到struct
如果要把表单里的内容赋值到一个 struct 里,除了用上面的方法一个一个获取再赋值外,beego 提供了通过另外一个更便捷的方式,就是通过 struct 的字段名或 tag 与表单字段对应直接解析到 struct。
定义 struct:
type user struct {Id int `form:"-"`Name interface{} `form:"username"`Age int `form:"age"`Email string
}
表单:
<form id="user">名字:<input name="username" type="text" />年龄:<input name="age" type="text" />邮箱:<input name="Email" type="text" /><input type="submit" value="提交" />
</form>
Controller 里解析:
func (this *MainController) Post() {u := user{}if err := this.ParseForm(&u); err != nil {//handle error}
}
注意,定义的struct如果有tag,就对应form里面的name,没有tag,就会把name赋值给字段名一样的字段。
ParseForm传入参数必须是一个struct的指针
获取 Request Body 里的内容
在 API 的开发中,我们经常会用到 JSON
或 XML
来作为数据交互的格式,如何在 beego 中获取 Request Body 里的 JSON 或 XML 的数据呢?
在配置文件里设置
copyrequestbody = true
在 Controller 中
func (this *ObjectController) Post() {var ob models.Objectvar err errorif err = json.Unmarshal(this.Ctx.Input.RequestBody, &ob); err == nil {objectid := models.AddOne(ob)this.Data["json"] = "{\"ObjectId\":\"" + objectid + "\"}"} else {this.Data["json"] = err.Error()}this.ServeJSON()
}
文件上传
在 beego 中你可以很容易处理文件上传,就是别忘记在你的 form 表单中增加这个属性 enctype="multipart/form-data"
,否则你的浏览器不会传输你的上传文件。
文件上传之后一般是放在系统的内存里面,如果文件的 size 大于设置的缓存内存大小,那么就放在临时文件中,默认的缓存内存是 64M,你可以通过如下来调整这个缓存内存大小:
beego.MaxMemory = 1<<22
或者在配置文件中通过如下设置:
maxmemory = 1<<22
Beego 提供了两个很方便的方法来处理文件上传:
GetFile(key string) (multipart.File,
*multipart.FileHeader
, error)该方法主要用于用户读取表单中的文件名
the_file
,然后返回相应的信息,用户根据这些变量来处理文件上传:过滤、保存文件等。SaveToFile(fromfile, tofile string) error
该方法是在 GetFile 的基础上实现了快速保存的功能 fromfile 是提交时候的 html 表单中的 name
<form enctype="multipart/form-data" method="post"><input type="file" name="uploadname" /><input type="submit">
</form>
保存的代码例子如下:
func (c *FormController) Post() {f, h, err := c.GetFile("uploadname")if err != nil {log.Fatal("getfile err ", err)}defer f.Close()c.SaveToFile("uploadname", "static/upload/" + h.Filename) // 保存位置在 static/upload, 没有文件夹要先创建}
直接绑定数据到对象
支持从用户请求中直接bind数据到指定的对象,例如请求地址如下
?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie
var id int
this.Ctx.Input.Bind(&id, "id") //id ==123var isok bool
this.Ctx.Input.Bind(&isok, "isok") //isok ==truevar ft float64
this.Ctx.Input.Bind(&ft, "ft") //ft ==1.2ol := make([]int, 0, 2)
this.Ctx.Input.Bind(&ol, "ol") //ol ==[1 2]ul := make([]string, 0, 2)
this.Ctx.Input.Bind(&ul, "ul") //ul ==[str array]user struct{Name}
this.Ctx.Input.Bind(&user, "user") //user =={Name:"astaxie"}
Session设置
beego 内置了 session 模块,目前 session 模块支持的后端引擎包括 memory、cookie、file、mysql、redis、couchbase、memcache、postgres,用户也可以根据相应的 interface 实现自己的引擎。
beego 中使用 session 相当方便,只要在 main 入口函数中设置如下:
beego.BConfig.WebConfig.Session.SessionOn = true
或者通过配置文件配置如下:
sessionon = true
通过这种方式就可以开启 session,如何使用 session,请看下面的例子:
func (this *MainController) Get() {v := this.GetSession("asta")if v == nil {this.SetSession("asta", int(1))this.Data["num"] = 0} else {this.SetSession("asta", v.(int)+1)this.Data["num"] = v.(int)}this.TplName = "index.tpl"
}
session 有几个方便的方法:
SetSession(name string, value interface{})
GetSession(name string) interface{}
DelSession(name string)
SessionRegenerateID()
DestroySession()
session 操作主要有设置 session、获取 session、删除 session。
当然你可以通过下面的方式自己控制这些逻辑:
sess:=this.StartSession()
defer sess.SessionRelease()
关于 Session 模块使用中的一些参数设置:
beego.BConfig.WebConfig.Session.SessionOn
设置是否开启 Session,默认是 false,配置文件对应的参数名:sessionon。
beego.BConfig.WebConfig.Session.SessionProvider
设置 Session 的引擎,默认是 memory,目前支持还有 file、mysql、redis 等,配置文件对应的参数名:sessionprovider。
beego.BConfig.WebConfig.Session.SessionName
设置 cookies 的名字,Session 默认是保存在用户的浏览器 cookies 里面的,默认名是 beegosessionID,配置文件对应的参数名是:sessionname。
beego.BConfig.WebConfig.Session.SessionGCMaxLifetime
设置 Session 过期的时间,默认值是 3600 秒,配置文件对应的参数:sessiongcmaxlifetime。
beego.BConfig.WebConfig.Session.SessionProviderConfig
设置对应 file、mysql、redis 引擎的保存路径或者链接地址,默认值是空,配置文件对应的参数:sessionproviderconfig。
beego.BConfig.WebConfig.Session.SessionHashFunc
默认值为 sha1,采用 sha1 加密算法生产 sessionid
beego.BConfig.WebConfig.Session.SessionHashKey
默认的 key 是 beegoserversessionkey,建议用户使用的时候修改该参数
beego.BConfig.WebConfig.Session.SessionCookieLifeTime
设置 cookie 的过期时间,cookie 是用来存储保存在客户端的数据。
过滤器
beego 支持自定义过滤中间件,例如安全验证,强制跳转等。
过滤器函数如下所示:
beego.InsertFilter(pattern string, position int, filter FilterFunc, params ...bool)
InsertFilter 函数的三个必填参数,一个可选参数
pattern 路由规则,可以根据一定的规则进行路由,如果你全匹配可以用
*
position 执行 Filter 的地方,五个固定参数如下,分别表示不同的执行过程
BeforeRouter 寻找路由之前
BeforeExec 找到路由之后,开始执行相应的 Controller 之前
AfterExec 执行完 Controller 逻辑之后执行的过滤器
FinishRouter 执行完逻辑之后执行的过滤器
BeforeStatic 静态地址之前
filter filter 函数 type FilterFunc func(*context.Context)
params
设置 returnOnOutput 的值(默认 true), 如果在进行到此过滤之前已经有输出,是否不再继续执行此过滤器,默认设置为如果前面已有输出(参数为true),则不再执行此过滤器
是否重置 filters 的参数,默认是 false,因为在 filters 的 pattern 和本身的路由的 pattern 冲突的时候,可以把 filters 的参数重置,这样可以保证在后续的逻辑中获取到正确的参数,例如设置了
/api/*
的 filter,同时又设置了/api/docs/*
的 router,那么在访问/api/docs/swagger/abc.js
的时候,在执行 filters 的时候设置:splat
参数为docs/swagger/abc.js
,但是如果不清楚 filter 的这个路由参数,就会在执行路由逻辑的时候保持docs/swagger/abc.js
,如果设置了 true,就会重置:splat
参数.
如下例子所示,验证用户是否已经登录,应用于全部的请求:
var FilterUser = func(ctx *context.Context) {_, ok := ctx.Input.Session("uid").(int)if !ok && ctx.Request.RequestURI != "/login" {ctx.Redirect(302, "/login")}
}beego.InsertFilter("/*",beego.BeforeRouter,FilterUser)
格式数据输出
Beego 当初设计的时候就考虑了 API 功能的设计,而我们在设计 API 的时候经常是输出 JSON 或者 XML 数据,那么 beego 提供了这样的方式直接输出:
注意 struct 属性应该 为 exported Identifier 首字母应该大写
JSON 数据直接输出:
func (this *AddController) Get() {mystruct := { ... }this.Data["json"] = &mystructthis.ServeJSON()}
调用 ServeJSON 之后,会设置
content-type
为application/json
,然后同时把数据进行 JSON 序列化输出。XML 数据直接输出:
func (this *AddController) Get() {mystruct := { ... }this.Data["xml"]=&mystructthis.ServeXML()}
调用 ServeXML 之后,会设置
content-type
为application/xml
,同时数据会进行 XML 序列化输出。jsonp 调用
func (this *AddController) Get() {mystruct := { ... }this.Data["jsonp"] = &mystructthis.ServeJSONP()}
调用 ServeJSONP 之后,会设置
content-type
为application/javascript
,然后同时把数据进行 JSON 序列化,然后根据请求的 callback 参数设置 jsonp 输出。
开发模式下序列化后输出的是格式化易阅读的 JSON 或 XML 字符串;在生产模式下序列化后输出的是压缩的字符串。
model
beego ORM 是一个强大的 Go 语言 ORM 框架。她的灵感主要来自 Django ORM 和 SQLAlchemy。
目前该框架仍处于开发阶段,可能发生任何导致不兼容的改动。
已支持数据库驱动:
MySQL:github.com/go-sql-driver/mysql
PostgreSQL:github.com/lib/pq
Sqlite3:github.com/mattn/go-sqlite3
以上数据库驱动均通过基本测试,但我们仍需要您的反馈。
ORM 特性:
支持 Go 的所有类型存储
轻松上手,采用简单的 CRUD 风格
自动 Join 关联表
跨数据库兼容查询
允许直接使用 SQL 查询/映射
严格完整的测试保证 ORM 的稳定与健壮
更多特性请在文档中自行品读。
安装 ORM:
go get github.com/astaxie/beego/orm
beego/orm 的使用例子
后文例子如无特殊说明都以这个为基础。
models.go:
package mainimport ("github.com/astaxie/beego/orm"
)type User struct {Id intName stringProfile *Profile `orm:"rel(one)"` // OneToOne relationPost []*Post `orm:"reverse(many)"` // 设置一对多的反向关系
}type Profile struct {Id intAge int16User *User `orm:"reverse(one)"` // 设置一对一反向关系(可选)
}type Post struct {Id intTitle stringUser *User `orm:"rel(fk)"` //设置一对多关系Tags []*Tag `orm:"rel(m2m)"`
}type Tag struct {Id intName stringPosts []*Post `orm:"reverse(many)"` //设置多对多反向关系
}func init() {// 需要在init中注册定义的modelorm.RegisterModel(new(User), new(Post), new(Profile), new(Tag))
}
main.go
package mainimport ("fmt""github.com/astaxie/beego/orm"_ "github.com/go-sql-driver/mysql"
)func init() {orm.RegisterDriver("mysql", orm.DRMySQL)orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8")
}func main() {o := orm.NewOrm()o.Using("default") // 默认使用 default,你可以指定为其他数据库profile := new(Profile)profile.Age = 30user := new(User)user.Profile = profileuser.Name = "slene"fmt.Println(o.Insert(profile))fmt.Println(o.Insert(user))
}
更多操作参考[官方文档](ORM使用 · Go语言中文文档)
view
beego中使用的模板语法与GO模板语法基本相同,这里不再细讲,可以参考[文档](模板语法指南 · Go语言中文文档)
本次分享先到这里,感兴趣可以点个关注,大家一起交流!感谢大家!