Go语言的Web框架有非常多,在日常开发中使用的有: beego、gin、revel等。这些框架也是一部分初学者的起点,这个系列的文章将会记录一个Web框架的开发历程。
这个过程中会阅读并参考一些其他的开源框架并形成自己的代码,后续的文章大概也是这个节奏,不断完善框架。
完整代码:
AllenTom/harukagithub.com最简单的HTTP Server
先从最简单最原始的开始入手,在Go语言中需要一点简单的代码就可以生成一个Server,如下:
package
这里发现有三个点,一个是main函数中的http.HandleFunc方法,另一个是http.ListenAndServe,最后是pingHandlerFunc。
其中handler func是Router功能的一部分,从中我们可以设计出大致的样子。下文会详细描述这些组件。
Router
Router是实现路由选择、路由解析等功能。当请求到达时正确地路由至指定的handher。
如果你看过gin或者beego中的Router实现,它们通常采用树的数据结构存储。
例如echo框架中的Router(router.go)就有明显的特征:
type
因为一开始并不想搞得太复杂,这里暂时使用slice来保存。
type
pattern与handler func存在着映射关系(路由表),这里可以用map的数据结构存储,在这里使用一个struct来作为Entity来保存映射的关系。
type
Handler Func
go中handler func比较简单,我们需要再“裹上一层”(Context),这样就可以从Writer和Request中扩展更多功能。
这个设计在一些Web Framework中也是常见操作,这里放一些源码的链接:
- echo - context.go
- gin - context.go
- beego - context.go
这是放出gin中Context片段
// Context is the most important part of gin. It allows us to pass variables between middleware,
Context的生存周期通常贯穿整个请求-响应的过程。
如法炮制,将Writer和Request放在一个struct (即Context)中。
type
定义一个type,这是用户需要实现的Handler Func
type
到目前,我们已经将go的Handler Func包装完成。
Engine
engine是Web框架的入口。使用一个struct来保存类似:全局配置、一些子组件的入口,例如:Router、Render等。
在gin中,Engine的源码(gin.go)是这样的(省略了部分代码):
type
按照设计的思路,编写代码:
type
添加RunAndListen方法,这里需要将之Router中的路由表项(Handlers)进行注册。
func
测试一下:
func
访问 http://localhost:8090/ping就能看到
{