参考其它Web框架来设计自己的框架.
Beego是基于MVC(Model-View-Controller)的,所以它定义了一个核心接口ControllerInterface.ControllerInterface定义了一个控制器必须要解决什么问题 .
示例:
定义Controller:
Copy package beego
import " github.com/beego/beego/v2/server/web "
type UserController struct {
web . Controller
}
func ( c * UserController ) GetUser () {
c . Ctx . WriteString ( " 你好,我是大明 " )
}
func ( c * UserController ) CreateUser () {
u := & User {}
err := c . Ctx . BindJSON ( u )
if err != nil {
c . Ctx . WriteString ( err . Error ())
return
}
_ = c . Ctx . JSONResp ( u )
}
type User struct {
Name string
} 可以看到,自定义的Controller是组合了Beego的web.Controller的.
使用Controller:
注意web.Router("/user", c, "get:GetUser"),将uri/user映射到了ControllerUserController的GetUser()方法上."get:GetUser"中的get要求HTTP动词为GET.
那么问题来了,Beego的核心抽象是什么?
ControllerInterfacearrow-up-right
Get()、Post()、Delete()、Put()、Head()、Patch()、Options()定义了如何处理HTTP动词
Init()、Prepare()、Finish()定义了一个Controller的生命周期.Prepare()类似于一个BeforeRequest的过程,Finish()类似于一个AfterRequest的过程,本质上二者都是回调
实际上刚刚示例中的web.Contrller就是接口ControllerInterface的默认实现.自定义的Controller只需组合web.Contrller即可
注意示例中的如下2行代码:
这说明用户虽然被要求组合web.Contrller,但路由注册和服务器启动是通过另一套机制来完成的.换言之,Beego框架中的路由注册与Controller的组合是无关的 .Controller仅仅用于帮助组织业务代码.
PART3. HttpServer和ControllerRegister
ControllerInterface可以看做核心接口,因为它直接体现了Beego的设计初衷:MVC模式.同时它也是用户核心接入点.
但是如果从功能特性上来说,HttpServerarrow-up-right 和ControllerRegisterarrow-up-right 才是核心
HttpServer:代表一个"服务器",大多数时候它就是一个进程.
当然你也可以做成1个进程监听多个端口的形式,但是端口与端口之间是资源隔离的
ControllerRegister:注册路由、路由匹配、执行业务代码都是通过它来完成的
PART4. Context抽象
和之前的内容相比,其他抽象更侧重于用户友好性.Contextarrow-up-right 抽象代表的是整个请求执行过程的上下文,用户操作请求和响应是通过Ctx来达成的.
实际上在Beego默认实现的Controller中也有这个Ctxarrow-up-right .一般情况下这个Ctx代表了整个请求过程的上下文.
Beego对Context进行了一个细分,分为Input和Output.Request字段是请求的副本,而ResponseWriter字段则是对响应的一个封装.
也有人认为Input应该包含Request,Output应该包含ResponseWriter,这样的设计会更清晰.
ControllerRegister:最为基础,它解决了路由注册 和路由匹配 这个基础问题
Context和Controller:为用户提供了丰富API,用于辅助构建系统
当然,硬要说的话,没有这二者也不是不行.只是用户需要手动和http.Request和http.ResponseWriter交互,这二者也只是对http.Request和http.ResponseWriter的封装
HttpServer:作为服务器抽象,用于管理应用生命周期和资源隔离单位
附录:1个进程监听2个端口的方法
此时访问localhost:8082/user是无法得到响应的.只有访问localhost:8081/user能够得到响应.
1个进程监听2个端口的使用场景:实时更新配置.例如同一个进程内,端口8081可以修改8082的内存