【新】7天用Go从零实现Web框架Gee教程-Day1
写在前面:
一年半前,这个系列就是学长推荐给我的,当时我还是初学 Go 的状态,不过学到一半没有继续下去,最近出于工作原因需要用到 Golang,翻找学习资料的时候忽然发现这个很久之前学的东西,很是喜欢,一年半时间过去,再次回望这个 Gee 系列,心中有了许多新的感悟,之前学的时候糊里糊涂,没有意识到研究这个具有的极大价值,算是朝花夕拾了。
Gee 是一个 类 Gin 的 Web 框架
首先认识到出于开发一个 Web 框架这个目的来说,我们需要开发的是什么
我们是基于标准库 “net/http” 进行进一步开发,net/http 包已提供的能力有监听端口,路由映射(静态),解析/构建 HTTP 包(解析 HTTP Req,构建 HTTP Resp)
那么我们可以进一步开发的功能有很多,比如:动态路由映射(在原有的静态路由升级而来),鉴权,处理 cookie、headers 等,插件功能
那么我们在开发 Web 框架之前,需要熟悉 net/http 的能力边界
今天使用 net/http 实现了最基本的 Web 功能:接收请求并返回。
不过即使是这个最基本的功能,也用到了 net/http 的三种能力:端口监听、路由映射(静态)、解析/构建 HTTP 包
我们在对于 net/http 包的抽象基本能力的了解基础上,进一步熟悉实现这些能力具体的函数(包括它的定义、输入参数、输出等)
端口监听:http.ListenAndServe(addr string, handler Handler)
路由映射(静态):http.HandleFunc(pattern string, handler Func(http.ResponseWriter, *http.Request))
解析/构建 HTTP 包:http.Request、http.ResponseWriter 具备这俩功能的东西——“请求处理器” Handler,它本身是一个接口(接口就是用于描述一种东西)
type Handler interface { |
整合这些相关函数,我们得到了最简单的 Web 服务
package main |
通过终端执行命令 curl localhost:8000 来进行测试验证,控制台会打印 index
遐思 - 1
能不能导入 net 包,写成 net.ListenAndServe ?
import ( |
不行,虽然从文件结构上来说 net 文件夹包含了 http 文件夹,但是从包管理来看,net 包 和 net/http 包毫无关系,相互独立。
疑惑 - 1
func main() { |
使用 Ghrome 浏览器 发起一次 localhost:8000 请求进行测试,打印两次 index
浏览器发送请求时会自动发送一个 localhost:8000/favicon.ico,打开开发者工具可以看到该请求
并且因为 “/“ 是通配符,所以两种路径的请求都会触发 indexHandler(通配符另外讨论)
可以通过 curl 命令发送纯净的请求进行测试
遐思 - 2
为什么 http.HandleFunc(pattern string, handler Func(http.ResponseWriter, *http.Request)) 的第二个参数不用 Handler 接口而用了一个类似的 函数,其实没什么深意,或者说有深意,就是偷懒,是一种“语法糖” 标准做法是这样的:func Handle(pattern string, handler Handler) 简化做法:func HandleFunc(pattern string, func(http.ResponseWriter, *http.Request)) (其实关于这点在函数名 Handle 和 HandleFunc 里就可以窥见一二,Go 的发明者对于函数起名还是很讲究的)
因为如果我们要创建一个实现 Handler 接口的对象相对比较繁琐,需要这样写:
func main() { |
不过 函数 和 对象 还有其他区别,函数无法存储数据,只能输入输出;而对象可以存储数据,像图中的 name。所以说用对象这种方式的可操作空间更大



