Abstract:
终于要跟go语言沾边了,到此,作者还有点小小的兴奋呢,也不知道为啥!
不管你之前是否从事过web相关的开发,相信你一定听过【框架】这个词,不为什么,因为随着社会的发展进步,被前人总结出来的架构,经验等等,系统的、可复用的东西,我们都能认为其为框架。既然说到了框架,那么毫无疑问,我们这里要用框架了,不要问我为什么,因为时间宝贵,我们没有必要重复造轮子,当然如果你想自己写框架的话,那我这里要祝你好运!平时在工作中会同时写python和go。截止目前, 用python的时间要比用go的时间要长,各种python框架如django、flask、tornado、scrapy等都有所涉猎。而go的web框架用的还不多,所以在这里我对go的几种框架做一个简单的调研与比较,然后做一个产品选型。
一、 Beego https://beego.me/
框架特性:
- 简单化:RESTful 支持、MVC 模型,可以使用 bee工具快速地开发应用,包括监控代码修改进行热编译、自动化测试代码以及自动化打包部署。
- 智能化:支持智能路由、智能监控,可以监控 QPS、内存消耗、CPU 使用,以goroutine 的运行状况,让您的线上应用尽在掌握。
- 模块化:beego 内置了强大的模块,包括 Session、缓存操作、日志记录、配置解析、性能监控、上下文操作、ORM模块、请求模拟等强大的模块,足以支撑你任何的应用。
- 高性能:beego 采用了 Go 原生的 http 包来处理请求,goroutine 的并发效率足以应付大流量的 Web 应用和 API应用,目前已经应用于大量高并发的产品中。
二、 Revel http://revel.github.io/
框架特性:
- 热编译:编辑, 保存, 和 刷新时,Revel自动编译代码和模板,如果代码编译错误,会给出一个 错误提示,同时捕捉 运行期错误。
- 全栈功能: Revel 支持: 路由, 参数解析, 验证, session/flash, 模板, 缓存, 计划任务, 测试, 国际化等功能。
- 高性能:Revel 基于 Go HTTP server 构建。 这是techempower发布的 最新评测结果 。在各种不同的场景下进行了多达三到十次的请求负载测试。
- 模块化:Revel框架由被称为 过滤器 的中间件组成,它实现了几乎所有的请求处理功能。 开发者可以自由地使用自定义的过滤器,比如如自定义的路由器,用以替换Revel默认的路由过滤器。
三、Martini http://martini.codegangsta.io
其他还有类似Goji,Gin,Traffic,Faygo,essgo, Macaron, GoInk, Baa等等,如果大家有感兴趣的可以自己搜来看看。
在本文中,综合考虑文档使用广泛度,文档的完整度,以及其他各种说不清道不明的原因,本文决定使用Beego框架安装: 需要安装Beego和Bee的开发工具 go get -u github.com/astaxie/beego go get -u github.com/beego/bee
安装完成之后,在命令行中输入bee 会有如下输出:
创建一个新的web项目,项目名称就简单叫systemAdmin吧!
看提示可以知道我们已经成功创建了名字叫systemAdmin 的项目,我们来看看初始化的项目的目录结构:
看这个目录结构是不是觉得很清晰?是的,确实很清晰,也比较干净,不像之前我们初始化的前端代码,有很多东西。
接下来我们同bee run 运行项目看看:
打开浏览器,我们可以看到,项目已经在http://localhost:8080/ 地址启动了,接下来我们来看看beego的MVC架构,为我们接下来的开发打好基础,同时也了解一下如果要想实现一个自己的框架,或许我们能从中了解到一个架构的设计。
文字描述如下:
在监听的端口接收数据,默认监听在 8080 端口。
用户请求到达 8080 端口之后进入 beego 的处理逻辑。
初始化 Context 对象,根据请求判断是否为 WebSocket 请求,如果是的话设置 Input,同时判断请求的方法是否在标准请求方法中(GET、POST、PUT、DELETE、PATCH、OPTIONS、HEAD),防止用户的恶意伪造请求攻击造成不必要的影响。
执行 BeforeRouter 过滤器,当然在 beego 里面有开关设置。如果用户设置了过滤器,那么该开关打开,这样可以提高在没有开启过滤器的情况下提高执行效率。如果在执行过滤器过程中,responseWriter 已经有数据输出了,那么就提前结束该请求,直接跳转到监控判断。
开始执行静态文件的处理,查看用户的请求 URL 是否和注册在静态文件处理 StaticDir 中的 prefix 是否匹配。如果匹配的话,采用 http包中默认的 ServeFile 来处理静态文件。
如果不是静态文件开始初始化 session 模块(如果开启 session 的话),这个里面大家需要注意,如果你的 BeforeRouter 过滤器用到了 session 就会报错,你应该把它加入到 AfterStatic 过滤器中。
开始执行 AfterStatic 过滤器,如果在执行过滤器过程中,responseWriter 已经有数据输出了,那么就提前结束该请求,直接跳转到监控判断。
执行过过滤器之后,开始从固定的路由规则中查找和请求 URL 相匹配的对象。这个匹配是全匹配规则,即如果用户请求的 URL 是 /hello/world,那么固定规则中 /hello 是不会匹配的,只有完全匹配才算匹配。如果匹配的话就进入逻辑执行,如果不匹配进入下一环节的正则匹配。
正则匹配是进行正则的全匹配,这个正则是按照用户添加 beego 路由顺序来进行匹配的,也就是说,如果你在添加路由的时候你的顺序影响你的匹配。和固定匹配一样,如果匹配的话就进行逻辑执行,如果不匹配进入 Auto 匹配。
如果用户注册了 AutoRouter,那么会通过 controller/method 这样的方式去查找对应的 Controller 和他内置的方法,如果找到就开始执行逻辑,如果找不到就跳转到监控判断。
如果找到 Controller 的话,那么就开始执行逻辑,首先执行 BeforeExec 过滤器,如果在执行过滤器过程中,responseWriter 已经有数据输出了,那么就提前结束该请求,直接跳转到监控判断。
Controller 开始执行 Init 函数,初始化基本的一些信息,这个函数一般都是 beego.Controller 的初始化,不建议用户继承的时候修改该函数。
是否开启了 XSRF,开启的话就调用 Controller 的 XsrfToken,然后如果是 POST 请求就调用 CheckXsrfCookie 方法。
继续执行 Controller 的 Prepare 函数,这个函数一般是预留给用户的,用来做 Controller 里面的一些参数初始化之类的工作。如果在初始化中 responseWriter 有输出,那么就直接进入 Finish 函数逻辑。
如果没有输出的话,那么根据用户注册的方法执行相应的逻辑,如果用户没有注册,那么就调用 http.Method 对应的方法(Get/Post 等)。执行相应的逻辑,例如数据读取,数据赋值,模板显示之类的,或者直接输出 JSON 或者 XML。
如果 responseWriter 没有输出,那么就调用 Render 函数进行模板输出。
执行 Controller 的 Finish 函数,这个函数是预留给用户用来重写的,用于释放一些资源。释放在 Init 中初始化的信息数据。
执行 AfterExec 过滤器,如果有输出的话就跳转到监控判断逻辑。
执行 Controller 的 Destructor,用于释放 Init 中初始化的一些数据。
如果这一路执行下来都没有找到路由,那么会调用 404 显示找不到该页面。
最后所有的逻辑都汇聚到了监控判断,如果用户开启了监控模块(默认是开启一个 8088 端口用于进程内监控),这样就会把访问的请求链接扔给监控程序去记录当前访问的 QPS,对应的链接访问的执行时间,请求链接等。
既然了解完了整个框架的结构,那么接下来,我们简单的实现一下GET/POST请求,作为我们整个项目初始化的练手:
GET /POST: 从前面了解到整个框架的入口函数为main.go 路由函数为router.go 所以我们首先需要在router.go中设置好路由 代码如下:
package routers
import (
"github.com/astaxie/beego"
"systemAdmin/controllers"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/username", &controllers.UserController{})
beego.Router("/login", &controllers.LoginController{})
}
设定好了路由,接下来需要去实现Controller,分别为UserController与LoginController,代码如下:
package controllers
import (
"github.com/astaxie/beego"
"strconv"
"strings"
)
type MainController struct {
beego.Controller
}
func (c *MainController) Get() {
c.Data["Website"] = "magic.chen"
c.Data["Email"] = "cfqcsunng@gmail.com"
c.TplName = "index.tpl"
}
// 基本的GET请求获取用户名
type UserController struct {
beego.Controller
}
type Date struct {
name string
age int
sex string
}
func (c *UserController) Get() {
data := Date{"magic", 24, "男"}
content := strings.Join([]string{"姓名:" + data.name, "性别:" + data.sex, "年龄:" + strconv.Itoa(data.age)}, " ")
c.Ctx.WriteString(content)
}
// 基本的Post请求
type LoginController struct {
beego.Controller
}
func (c *LoginController) Post() {
username := c.GetString("username")
password := c.GetString("password")
content := strings.Join([]string{"用户名:" + username, "密码:" + password}, " ")
c.Ctx.WriteString(content)
}
查看访问结果:
GET:
POST:
post我们用postman工具来测试:
可以看到输出结果跟我们的输入一致。ok,这里简单的介绍了利用Beego框架初始化一个项目,并简单实现了两种最常见的web请求,GET/POST,到此,我们的后端项目初始化工作就算基本完成了,既然前后端的项目都已经搭建ok了,接下来的工作也就真正步入正轨了,在接下来的一系列课程中,我们会详细的看到,如果进行前后端交互,如何一步步的开发一个完善的企业后台管理系统。
那么,尽情期待吧!
参考目录:
- https://beego.me/docs/mvc/
- https://www.zhihu.com/question/27370112
- build-web-application-with-golang
有疑问加站长微信联系(非本文作者)