目錄
- 第一天:前置知識(http.Handler接口),Code - Github
- 第二天:上下文設計(Context),Code - Github
- 第三天:Tire樹路由(Router),Code - Github
- 第四天:分組控制(Group),Code - Github
- 第五天:中間件(Middleware),Code - Github
- 第六天:HTML模板(Template),Code - Github
- 第七天:錯誤恢復(Panic Recover),Code - Github
設計一個框架
大部分時候,我們需要實現一個 Web 應用,第一反應是應該使用哪個框架。不同的框架設計理念和提供的功能有很大的差別。比如 Python 語言的 django
和flask
,前者大而全,后者小而美。Go語言/golang 也是如此,新框架層出不窮,比如Beego
,Gin
,Iris
等。那為什么不直接使用標准庫,而必須使用框架呢?在設計一個框架之前,我們需要回答框架核心為我們解決了什么問題。只有理解了這一點,才能想明白我們需要在框架中實現什么功能。
我們先看看標准庫net/http
如何處理一個請求。
func main() {
http.HandleFunc("/", handler)
http.HandleFunc("/count", counter)
log.Fatal(http.ListenAndServe("localhost:8000", nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}
net/http
提供了基礎的Web功能,即監聽端口,映射靜態路由,解析HTTP報文。一些Web開發中簡單的需求並不支持,需要手工實現。
- 動態路由:例如
hello/:name
,hello/*
這類的規則。 - 鑒權:沒有分組/統一鑒權的能力,需要在每個路由映射的handler中實現。
- 模板:沒有統一簡化的HTML機制。
- ...
當我們離開框架,使用基礎庫時,需要頻繁手工處理的地方,就是框架的價值所在。但並不是每一個頻繁處理的地方都適合在框架中完成。Python有一個很著名的Web框架,名叫bottle
,整個框架由bottle.py
一個文件構成,共4400行,可以說是一個微框架。那么理解這個微框架提供的特性,可以幫助我們理解框架的核心能力。
- 路由(Routing):將請求映射到函數,支持動態路由。例如
'/hello/:name
。 - 模板(Templates):使用內置模板引擎提供模板渲染機制。
- 工具集(Utilites):提供對 cookies,headers 等處理機制。
- 插件(Plugin):Bottle本身功能有限,但提供了插件機制。可以選擇安裝到全局,也可以只針對某幾個路由生效。
- ...
Gee 框架
這個教程將使用 Go 語言實現一個簡單的 Web 框架,起名叫做Gee
,geektutu.com
的前三個字母。我第一次接觸的 Go 語言的 Web 框架是Gin
,Gin
的代碼總共是14K,其中測試代碼9K,也就是說實際代碼量只有5K。Gin
也是我非常喜歡的一個框架,與Python中的Flask
很像,小而美。
7天實現Gee框架
這個教程的很多設計,包括源碼,參考了Gin
,大家可以看到很多Gin
的影子。
時間關系,同時為了盡可能地簡潔明了,這個框架中的很多部分實現的功能都很簡單,但是盡可能地體現一個框架核心的設計原則。例如Router
的設計,雖然支持的動態路由規則有限,但為了性能考慮匹配算法是用Trie樹
實現的,Router
最重要的指標之一便是性能。
希望這個教程能夠對你有所啟發,如果對 Gee 有任何好的建議,歡迎提issues - Github 和 PR。教程中的任何問題,可以直接在文章末尾評論。
推薦閱讀
原文地址:7天用Go從零實現Web框架Gee - 極客兔兔
知乎專欄: Go語言 - 極客兔兔
關注微博: @極客兔兔