go web 框架——初探
Go Web 框架自研——初探
beego 框架参考
这是 beego 启动一个 web 服务的基础用法:
1 | // controller.go |
1 | // controller_test.go |
可以看到,定义了一个 UserController 结构体,这个 controller 组合了 beego 的 web controller,提供了获取用户和创建用户两个方法。然后注册路由的时候把这个 controller 传了进去。
也就是说,beego 是按照 MVC 模式设计的,它要求使用者在业务层面上使用 MVC 模式组织自己的代码,也就是一个业务一个 controller 这个样子。不过我个人觉得,这种设计不是很好,是否使用 MVC 应该让使用者自己选择,而不应该让框架提供者来左右。
再来看一下定义 controller 的时候组合的 beego 的 web controller 定义:
这里有一个 ctx 字段,它的定义是:
1 | // Context Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter. |
可以看到,beego 在 ctx 里面存了请求和响应信息,以及自己的输入输出。我觉得这样有点重复了,很容易让使用者误解,为什么会有两个输入,两个输出,究竟应该使用哪个。
在启动 web 服务的时候,是直接使用的 web.Run 方法,这是 beego 提供的一个默认包变量,它的定义是:
可以看到,beego 抽象出了一个 server 层面上的结构体,这个结构体里面有一些字段,其中 LifeCycleCallbacks 也就是声明周期回调函数,用户可以控制服务启动前干些什么,启动后干些什么。Server 字段是 http 包里面的 Server 类型,可以用来启动服务。Handlers 字段的类型定义是这样的:
这里面有一个 routers 字段,它是一个 map 类型,存的是每个请求方法对应的路由树,用户注册的路由会存到这里面来。
通过这些,可以看到 beego 基本上有四个抽象:
- 路由(这个是最重要的)
- server
- context
- controller
server 负责把其它抽象组合起来,方便使用者使用,并且负责和 go 的 http 包打交道,在 server 层面上也提供了一些声明周期回调。
context 主要负责请求响应的传递,以及负责用户自定义的数据传递。
路由负责匹配请求和对应的业务处理方法。
controller 则负责业务处理。
整体样子就是:

其它框架参考
其它框架比如说 gin、iris、echo,用法上基本都相似,因为国内用 gin 也比较多嘛,所以这里以 gin 为例说明:
1 | // user_controller.go |
1 | // user_controller_test.go |
可以看到,和 beego 不同的是 gin 没有按照 MVC 模式设计自己的代码,而是让用户在注册路由的时候,传入一个 func(ctx *gin.Context)
类型的函数,框架将其抽象成了type HandlerFunc func(*Context)
。
这样的好处就是用户可以选择是否使用 MVC 模式来组织自己的代码。如果用户想要使用 MVC 模式,那么只需要按照这个函数类型设计自己的方法就可以了。
gin 的 Context 也和 beego 类似:
至于 beego 的 httpServer,gin 里面是 Engine:
而且 gin 的 Engine,实现了 http 包里面的 Handler 接口:
也就意味着,我可以使用 gin 包提供的启动方法,也可以创建一个 gin 的 Engine,然后使用 http 包里面的 ListenAndServe 启动它。
然后 Engine 结构体组合了 RouterGroup,其定义为:
1 | // RouterGroup is used internally to configure router, a RouterGroup is associated with |
这里面存在和 Engine 的一个双向引用关系,gin 可能是需要在 RouterGroup 上拿到 engine 进行一些操作。
对于 gin 的路由注册:
可以看到 gin 为不同的请求方法提供了不同的实现,不过最终都会调到 handle 方法上。这里我认为可以只提供一个 Handle 方法,不用提供 GET、POST 等这些实现,这样可以让接口尽可能的小而美。
可以看到 gin 也差不多设计成了这幅样子:
- Engine
- 路由 RouterGroup
- Context
- HandlerFunc
和 beego 一样,只不过名字不用而已。

其它几个框架类似,这里就不详细说了。
总结
可以看到这些 web 框架,基本上都是一副鬼样子,有 server、路由、context、业务处理四个抽象。
server 负责和 go 的 http 包打交道,负责 web 服务的启动终止、生命周期管理,以及将路由注册、业务处理这些抽象组织在一起,方便框架者使用。
context 负责数据管理,请求响应内容处理。
业务处理负责组织使用者的业务代码。
路由注册负责绑定号好不同的请求方法和路径对应的业务处理逻辑。