7天用Go動手寫/從零實現Web框架Gee
設計一個框架
大部分時候,我們需要實現一個 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
Flask
很像,小而美。
7天實現Gee框架
這個教程的很多設計,包括原始碼,參考了Gin
,大家可以看到很多Gin
的影子。
時間關係,同時為了儘可能地簡潔明瞭,這個框架中的很多部分實現的功能都很簡單,但是儘可能地體現一個框架核心的設計原則。例如Router
的設計,雖然支援的動態路由規則有限,但為了效能考慮匹配演算法是用Trie樹
實現的,Router
最重要的指標之一便是效能。
希望這個教程能夠對你有所啟發,如果對 Gee 有任何好的建議,歡迎提issues - Github 和 PR。教程中的任何問題,可以直接在文章末尾評論。
目錄
- 第一天:前置知識(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
推薦閱讀
- Go 語言簡明教程
- Go Test 簡明教程
- Go Gin 簡明教程
原文地址:7天用Go從零實現Web框架Gee - 極客兔