Golang Web 框架 Beego

504 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

Beego应该是Golang开源社区里面做的最早的、最成熟的Web框架;针对Web开发中所用到的Task(任务管理)、ORM(数据库关系映射)、Log(系统日志)、Metrics(系统监测)等诸多模块都进行了封装,让以前使用过 Tornado、ThinkPHP 这种web框架的用户可以按照Web开发的流程快速上手学习,不过这也导致了一个被大家所诟病的问题:系统太过冗杂,很多模块都用不到,不符合Golang的极简原则。

Github地址:github.com/beego/beego

安装

使用GoModule初始化项目后,使用以下命令安装beego

go get github.com/beego/beego

启动

使用beego.Run()方法可以在8080端口上启动一个Web服务,如果需要对其他的端口进行监听,可在Run方法中通过:8000这种方式的传参来进行控制

// 默认监听 8080 端口
beego.Run()
// 监听 8000 端口
beego.Run(":8000")

路由

针对路由的规则定义、参数传递通常有两种处理方法:使用自定义Controller整体控制、使用HTTP方法针对性控制

自定义Controller整体控制

自定义Controller的处理流程相对而言较为麻烦,整体逻辑分为以下三步:

  1. 定义一个Struct并继承beego.Controller方法;
  2. 根据业务要求选择需要实现的方法,如下所示实现一个Get方法
// 定义 Controller 结构体
type MainController struct {
   beego.Controller
}
// 实现 Get 方法
func (c *MainController) Get()  {
   c.Ctx.WriteString("Hello World")
}
  1. 通过 beego.Router() 约定URI与Controller的映射关系
// curl http://localhost:8080/
// response ==> Hello World
beego.Router("/", &MainController{})

通过HTTP方法针对性控制

beego针对http的常规方法(GET、POST、PUT、DELETE等)都进行了封装;直接参考以下代码,将Get修改为需要监听的方法,将具体的处理逻辑修改为其相对应的业务逻辑即可。

beego.Get("/ping", func(c *context.Context) {
   c.WriteString("pong")
})

获取URL后的参数

通过c.Input.Query()方法获取URL中?后面传递过来的参数

// 获取 URL 上传递过来的 name
c.Input.Query("name")

获取URI上的参数

通过c.Input.Param()方法获取URI上的参数,如下所示:在URI上定义了:name占位符,使用c.Input.Param(":name")获取:name占位符上传递过来的参数

// curl http://localhost:8080/param/mmc
// response ==> Param : mmc

beego.Get("/param/:name", func(c *context.Context) {
   c.WriteString("Param : " + c.Input.Param(":name"))
})

获取表单中的参数

通过c.Request.PostFormValue()方法获取表单传递过来的参数

// 获取表单中 name 对应的值
c.Request.PostFormValue("name")

获取以JSON格式传递过来的参数

需要定义一个BindJson的函数,不过这个方法后面可以直接调用,整体分为三个步骤:

  1. 定义 BindJson 函数,将Body中的数据扫描到结构体上
func BindJson(body io.ReadCloser, v interface{}) error {
   b, err := io.ReadAll(body)
   if err != nil {
      return err
   }
   err = json.Unmarshal(b, v)
   return err
}
  1. 定义一个用于扫描数据的结构体,按照具体需要定义即可,参考如下:
type Person struct {
   Name string `json:"name"`
}
  1. 在路由函数中使用BindJson方法对数据进行映射
// curl -X POST -H 'Content-Type: application/json' -d '{"name":"mmc"}' 127.0.0.1:8080/json
// response ==> Person => mmc
beego.Post("/json", func(c *context.Context) {
   p := new(Person)
   BindJson(c.Request.Body, p)
   c.WriteString("Person => " + p.Name)
})

返回值类型

beego的返回数据支持:“常用数据格式的返回” 以及“将数据映射到模板中”两种格式

返回数据

框架支持Json、Xml、Yaml、String等多种格式的返回,通过 c.Output.JSON() 的方式来使用,

c.Output.JSON(beego.M{
   "code": 200,
   "msg": "Success",
}, false, false)

映射模板

往模板映射的这种方式需要是“自定义Controller整体控制”才支持。模板的默认地址为 “views/控制器/请求方法.tpl” 例如:views/maincontroller/get.tpl ;可以通过 c.TplName="index.tpl" 这种方式修改默认的模板位置,通过这种方式指定后模板的存储位置为views/index.tpl;通过 c.Data["name"] = "get" 这种方式往模板传递参数,模板中通过 {{.name}} 这种方式获取参数。

  1. 定义Controller及相关的模板数据
type MainController struct {
   beego.Controller
}

func (c *MainController) Get()  {
   c.Data["name"] = "mmc" // 往模板中传递 name 参数
   c.TplName = "index.tpl" // 定义处理数据的模板名称
}
  1. 定义路由关联Controller
beego.Router("/", &MainController{})
  1. 定义模板显示数据
<h1>name => {{.name}}</h1>

ORM

beego 与目前Golang Web社区较大的差别在于ORM这块,目前流行的Web框架都是专注于HTTP服务这一块,对数据库相关的操作则是交给GORM、XORM等成熟的ORM框架。而beego自己对对数据库的操作进行了封装,避免了用户再额外安装第三方包。

使用ORM之前需要依次进行以下的初始化操作(注:本案例使用MySQL):

// 1. 确定已导入 mysql 的包
import _ "github.com/go-sql-driver/mysql"

// 2. 定于需要关联的数据库模型
type User struct {
   Id   int    `json:"id"`
   Name string `json:"name"`
}

// 3. 初始化数据库配置
// 注册数据库
orm.RegisterDataBase("default", "mysql", "root:passport@tcp(localhost:3306)/test?charset=utf8")
// 注册model
orm.RegisterModel(new(User))
o := orm.NewOrm()
// 指定使用上面初始化的 default 数据库
o.Using("default")

CRUD

  • 查询

查询ID为1的用户:初始化User时,指定Id的值为1,通过 Read 方法查询User对应的值

u := &User{Id: 1}
err := o.Read(u)
  • 新增

使用 Insert 方法往表中新增数据

u := &User{
   Name: "get",
}
_, err := o.Insert(u)
  • 修改

使用 Update 方法修改数据,默认使用Id作为匹配条件,可通过Update的第二个参数修改匹配条件,如下:更新Id为1的用户数据

u := &User{
   Id: 1,
   Name: "char",
}
_, err := o.Update(u)
  • 删除

使用 Delete 方法删除数据,如下所示删除Id为1的用户数据

u := &User{
   Id: 1,
}
_, err := o.Delete(u)

支持原生SQL

通过 o.Raw() 方法可以获取 RawSeter 对象,使用RawSeter中的Exec、QueryRow等方法来执行SQL并获取相关的结果,如下所示查询ID为2的用户数据

u := new(User)
o.Raw("SELECT * FROM user WHERE id = ?", 2).QueryRow(u)