前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个web框架最核心的就那十几行,你知道么?

一个web框架最核心的就那十几行,你知道么?

作者头像
小锟哥哥
发布2022-05-10 09:01:09
1620
发布2022-05-10 09:01:09
举报
文章被收录于专栏:GoLang全栈

当我们在《 原地起飞,带你揭晓 Go web 框架底层原理!》这边文章中把请求全接管后,接下来我们要做的就是开始内部消化这些请求了。

现在我们需要开始封装我们自己的处理模块了。

初步的文件结构划分

首先我们需要新建一个名为 kun 的文件夹,你也可以用你自己喜欢的名字,用来存放我们的框架代码。

现在我们写项目大都使用的 go mod 来管理我们的依赖,所以我们也通过 go mod 来引入我们的库。

这样能起到解耦的作用,完事之后我们还能把这个模块放到我们的仓库里面。

工程里面的 go.mod 文件内容:

代码语言:javascript
复制
module kun-demo

go 1.17

require kun v0.0.1

replace kun => ./kun

kun文件夹里面的 go.mod 文件内容:

代码语言:javascript
复制
module kun

go 1.17

对于不知道为什么要这样写的同学,可以去补一补 go mod 的基础知识哦,这里不做展开讲解。

完成的效果

首先我们先来看下,这篇文章最后要达到的使用效果:

代码语言:javascript
复制
func main() {
 engine := kun.New()
 engine.GET("/", func(w http.ResponseWriter, req *http.Request) {
  fmt.Fprintf(w, "URL.Path = %q\n", req.URL.Path)
 })
 engine.Run(":8081")
}

我们模仿了 gin 框架:

我们只需要调用下 kun 模块里面的 New 方法就可以得到一个引擎,随后就可以挂载我们的路由方法,最后直接 Run 就跑起来了。

关键点:

要实现上面的效果,最关键的点就是上一篇文章里面提到的:

go 基础 http 库,只要是实现了 ServeHTTP(*w* http.ResponseWriter, *req* http.Request) 这个方法就可以给挂到 http 里面。

所以我们只需要新建一个结构体,随后实现这个方法即可。

开始封装

知道了关键点,下面就开始写我们的模块代码:

实现核心功能:

在 kun.go 写上最核心的代码:

代码语言:javascript
复制
// 从定义方法
type HandleFun func(http.ResponseWriter, *http.Request)

// 核心结构体
type Engine struct {
 router map[string]HandleFun
}

func New() *Engine {
 return &Engine{
  router: make(map[string]HandleFun,0),
 }
}

//ServeHTTP 关键方法 实现 Handler 的接口
func (this *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 key := req.Method + "-" + req.URL.Path
 if handler,ok := this.router[key];ok {
  handler(w, req)
 }else{
  fmt.Fprintf(w,"404 Not Found: %s\n", req.URL)
 }
}

// 发射
func (this *Engine) Run(addr string) (err error) {
 return http.ListenAndServe(addr, this)
}

这里我们声明了一个 Engine 的结构体,里面我们声明了一个 map 类型的路由,这是为了方便挂载不同的方法。

同时因为 func(http.ResponseWriter, *http.Request) 这个方法会被经常用到,所以我们对他进行了重命名。

最关键的就是 ServeHTTP 方法了:

当我们的请求过来时,我们把他的 method 和 path 两个参数,合并起来,当做 key 去 router 里面查找这请求的处理方法,你也可以使用其他的处理方式。

最后就是 run 起来,把自己挂载到 http 里面。

这就是最最最核心的几行代码了!

开始完善周边方法

上面写完了核心代码,接下来就开始完善周边的方法,让调用的人使用起来更加的便利。

如果你不完善,其实也通过修改 Engine 里面的 router 属性,也能达到最后的效果,但是这样非常不友好。

所以,这里我们再加写两个方法!

代码语言:javascript
复制
func (this *Engine) AddRouter(method string, pattern string, handler HandleFun) {
 key := method + "-" + pattern
 this.router[key] = handler
}

func (this *Engine) GET(pattern string, handler HandleFun) {
 this.AddRouter("GET",pattern,handler)
}

你还可以加上 POST、PUT、DELETE 等方法的挂载入口。

我这里就不写了,大家自己完善吧。

我们的最初级的封装就完成了,现在你可以任意的挂载方法了。

接下来我会再进一步的迭代,下一篇文章我们会融入上下文功能,让我们的框架更加的好用

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GoLang全栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初步的文件结构划分
  • 完成的效果
    • 关键点:
    • 开始封装
      • 实现核心功能:
        • 开始完善周边方法
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档