本文主要分享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框架的安装
go
// 安装Beego框架
go get -u github.com/astaxie/beego
//安装Beego工具:
go get -u github.com/beego/bee
go get -u github.com/beego/bee/v2
go install github.com/beego/bee/v2@master
安装完成bee可执行性文件默认放在$GOPATH/bin
里面,所以需要把 $GOPATH/bin
添加到环境变量中
此处贴上如何配置环境变量
go$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命令
go
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.0
USAGE
bee command [arguments]
AVAILABLE COMMANDS
dev Commands which used to help to develop beego and bee
update Update Bee
version Prints the current Bee version
bale Transforms non-Go files to Go source files
fix Fixes your application by making it compatible with newer versions of Beego
dockerize Generates a Dockerfile and docker-compose.yaml for your Beego application
migrate Runs database migrations
new Creates a Beego application
pack Compresses a Beego application into a single file
rs Run customized scripts
server serving static content over HTTP on port
run Run the application by starting a local development server
pro Source code generator
api Creates a Beego API application
generate Source code generator
hprose Creates an RPC application based on Hprose and Beego frameworks
dlv Start a debugging session using Delve
Use 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
命令就来自动生成代码的,加快开发步骤,如:
go
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)/test
example: 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 controllers
bee generate view [viewpath]
generate CRUD view in viewpath
bee generate migration [migrationfile] [-fields=""]
generate migration file for making database schema update
-fields: a list of table fields. Format: field:type, ...
bee generate docs
generate swagger doc file
bee generate test [routerfile]
generate testcase
bee 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)/test
default 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目录下输入命令
go
bee new myproject
最后生成的目录结构如下
然后运行bee run
命令,成功启动
beego的MVC架构
controller
beego的配置文件
beego 目前支持 INI、XML、JSON、YAML 格式的配置文件解析,但是默认采用了 INI 格式解析,用户可以通过简单的配置就可以获得很大的灵活性。
go
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
go
appname = myproject
httpaddr = "127.0.0.1"
httpport = 9090
include "app2.conf"
app2.conf
go
runmode ="dev"
autorender = false
recoverpanic = false
viewspath = "myview"
[dev]
httpport = 8080
[prod]
httpport = 8088
[test]
httpport = 8888
配置文件解析支持从环境变量中获取配置项,配置项格式:${环境变量}
。例如下面的配置中优先使用环境变量中配置的 runmode 和 httpport,如果有配置环境变量 ProRunMode 则优先使用该环境变量值。如果不存在或者为空,则使用 "dev" 作为 runmode。
go
runmode = "${ProRunMode||dev}"
httpport = "${ProPort||9090}"
更多配置参数大家可以参考官网
beego的路由设置
1、基础路由
beego从1.2开始支持基本的RESTful函数式路由,大多定义在royters/router.go
文件中。最简单的 beego 路由由 URI 和闭包函数组成。
go
package routers
import (
"github.com/astaxie/beego"
)
func init() {
beego.Get("/", func(ctx *context.Context) {
ctx.Output.Body([]byte("Hello, world!")
)
})
}
所有支持的基础路由如下:
-
beego.Get(router, beego.FilterFunc)
-
beego.Post(router, beego.FilterFunc)
-
beego.Put(router, beego.FilterFunc)
-
beego.Patch(router, beego.FilterFunc)
-
beego.Head(router, beego.FilterFunc)
-
beego.Options(router, beego.FilterFunc)
-
beego.Delete(router, beego.FilterFunc)
-
beego.Any(router, beego.FilterFunc)
但是这种路由设置方式不利于代码组织和复用,也不符合beego框架的推荐时间
所以我们一般推荐使用RESTful形式,也就是将路由映射到控制器的方法
2、RESTful Controller 路由
2.1 固定路由
固定路由就是全匹配的路由
在controls/defualt.go
中设置控制器
go
ppackage controllers
import (
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
设置路由
go
package routers
import (
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
中设置控制器
go
type ListController struct {
beego.Controller
}
func (c *ListController) GetAllBooks() {
c.Ctx.WriteString("这是书籍列表")
}
func (c *ListController) AddBooks() {
c.Ctx.WriteString("添加书籍")
}
籍")
}
royters/router.go
设置路由
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")
}
go
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删除自动生成注解路由的功能需要手动生成,因此最新版本设置注解路由如下
go
package controllers
import (
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("添加书籍")
}
go
package routers
import (
beego "github.com/beego/beego/v2/server/web"
"myproject/controllers"
)
func init() {
beego.Include(&controllers.ListController{})
}
然后在自己项目目录终端运行以下命令
go
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)
命名空间可以对路由进行分类管理,便于维护
以下是一个简单的示例
go
package routers
import (
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/search
beego.NSRouter("/search", &controllers.UserControllers{}, "Get:SearchUser"),
// /api/user/add
beego.NSRouter("/add", &controllers.UserControllers{}, "Get:AddUser"),
// /api/user/:id/detail
beego.NSRouter("/:id/detail", &controllers.UserControllers{}, "Get:Detail"),
// /api/user/:id/delete
beego.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)
go
func (this *MainController) Post() {
jsoninfo := this.GetString("jsoninfo")
if jsoninfo == "" {
this.Ctx.WriteString("jsoninfo is empty")
return
}
}
其他类型如int类型
go
func (this *MainController) Post() {
id := this.Input().Get("id")
intid, err := strconv.Atoi(id)
}
2、直接解析到struct
如果要把表单里的内容赋值到一个 struct 里,除了用上面的方法一个一个获取再赋值外,beego 提供了通过另外一个更便捷的方式,就是通过 struct 的字段名或 tag 与表单字段对应直接解析到 struct。
定义 struct:
go
type user struct {
Id int `form:"-"`
Name interface{} `form:"username"`
Age int `form:"age"`
Email string
}
表单:
go
<form id="user">
名字:<input name="username" type="text" />
年龄:<input name="age" type="text" />
邮箱:<input name="Email" type="text" />
<input type="submit" value="提交" />
</form>
Controller 里解析:
go
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 中
go
func (this *ObjectController) Post() {
var ob models.Object
var err error
if 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,你可以通过如下来调整这个缓存内存大小:
go
beego.MaxMemory = 1<<22
或者在配置文件中通过如下设置:
go
maxmemory = 1<<22
Beego 提供了两个很方便的方法来处理文件上传:
-
GetFile(key string) (multipart.File,
*multipart.FileHeader
, error)该方法主要用于用户读取表单中的文件名
the_file
,然后返回相应的信息,用户根据这些变量来处理文件上传:过滤、保存文件等。 -
SaveToFile(fromfile, tofile string) error
该方法是在 GetFile 的基础上实现了快速保存的功能 fromfile 是提交时候的 html 表单中的 name
go
<form enctype="multipart/form-data" method="post">
<input type="file" name="uploadname" />
<input type="submit">
</form>
保存的代码例子如下:
go
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数据到指定的对象,例如请求地址如下
go
?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie
go
var id int
this.Ctx.Input.Bind(&id, "id") //id ==123
var isok bool
this.Ctx.Input.Bind(&isok, "isok") //isok ==true
var ft float64
this.Ctx.Input.Bind(&ft, "ft") //ft ==1.2
ol := 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 入口函数中设置如下:
go
beego.BConfig.WebConfig.Session.SessionOn = true
或者通过配置文件配置如下:
go
sessionon = true
通过这种方式就可以开启 session,如何使用 session,请看下面的例子:
go
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。
当然你可以通过下面的方式自己控制这些逻辑:
go
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 支持自定义过滤中间件,例如安全验证,强制跳转等。
过滤器函数如下所示:
go
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
参数.
如下例子所示,验证用户是否已经登录,应用于全部的请求:
go
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 数据直接输出:
gofunc (this *AddController) Get() { mystruct := { ... } this.Data["json"] = &mystruct this.ServeJSON() }
调用 ServeJSON 之后,会设置
content-type
为application/json
,然后同时把数据进行 JSON 序列化输出。 -
XML 数据直接输出:
gofunc (this *AddController) Get() { mystruct := { ... } this.Data["xml"]=&mystruct this.ServeXML() }
调用 ServeXML 之后,会设置
content-type
为application/xml
,同时数据会进行 XML 序列化输出。 -
jsonp 调用
gofunc (this *AddController) Get() { mystruct := { ... } this.Data["jsonp"] = &mystruct this.ServeJSONP() }
调用 ServeJSONP 之后,会设置
content-type
为application/javascript
,然后同时把数据进行 JSON 序列化,然后根据请求的 callback 参数设置 jsonp 输出。
开发模式下序列化后输出的是格式化易阅读的 JSON 或 XML 字符串;在生产模式下序列化后输出的是压缩的字符串。
model
beego ORM 是一个强大的 Go 语言 ORM 框架。她的灵感主要来自 Django ORM 和 SQLAlchemy。
目前该框架仍处于开发阶段,可能发生任何导致不兼容的改动。
已支持数据库驱动:
-
PostgreSQL:github.com/lib/pq
-
Sqlite3:github.com/mattn/go-sqlite3
以上数据库驱动均通过基本测试,但我们仍需要您的反馈。
ORM 特性:
-
支持 Go 的所有类型存储
-
轻松上手,采用简单的 CRUD 风格
-
自动 Join 关联表
-
跨数据库兼容查询
-
允许直接使用 SQL 查询/映射
-
严格完整的测试保证 ORM 的稳定与健壮
更多特性请在文档中自行品读。
安装 ORM:
go
go get github.com/astaxie/beego/orm
beego/orm 的使用例子
后文例子如无特殊说明都以这个为基础。
models.go:
go
package main
import (
"github.com/astaxie/beego/orm"
)
type User struct {
Id int
Name string
Profile *Profile `orm:"rel(one)"` // OneToOne relation
Post []*Post `orm:"reverse(many)"` // 设置一对多的反向关系
}
type Profile struct {
Id int
Age int16
User *User `orm:"reverse(one)"` // 设置一对一反向关系(可选)
}
type Post struct {
Id int
Title string
User *User `orm:"rel(fk)"` //设置一对多关系
Tags []*Tag `orm:"rel(m2m)"`
}
type Tag struct {
Id int
Name string
Posts []*Post `orm:"reverse(many)"` //设置多对多反向关系
}
func init() {
// 需要在init中注册定义的model
orm.RegisterModel(new(User), new(Post), new(Profile), new(Tag))
}
main.go
go
package main
import (
"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 = 30
user := new(User)
user.Profile = profile
user.Name = "slene"
fmt.Println(o.Insert(profile))
fmt.Println(o.Insert(user))
}
更多操作参考[官方文档](ORM使用 · Go语言中文文档)
view
beego中使用的模板语法与GO模板语法基本相同,这里不再细讲,可以参考[文档](模板语法指南 · Go语言中文文档)
本次分享先到这里,感兴趣可以点个关注,大家一起交流!感谢大家!