1. 程式人生 > >7天用Go動手寫/從零實現Web框架Gee

7天用Go動手寫/從零實現Web框架Gee

設計一個框架

大部分時候,我們需要實現一個 Web 應用,第一反應是應該使用哪個框架。不同的框架設計理念和提供的功能有很大的差別。比如 Python 語言的 djangoflask,前者大而全,後者小而美。Go語言/golang 也是如此,新框架層出不窮,比如BeegoGinIris等。那為什麼不直接使用標準庫,而必須使用框架呢?在設計一個框架之前,我們需要回答框架核心為我們解決了什麼問題。只有理解了這一點,才能想明白我們需要在框架中實現什麼功能。

我們先看看標準庫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/:namehello/*這類的規則。
  • 鑑權:沒有分組/統一鑑權的能力,需要在每個路由對映的handler中實現。
  • 模板:沒有統一簡化的HTML機制。
  • ...

當我們離開框架,使用基礎庫時,需要頻繁手工處理的地方,就是框架的價值所在。但並不是每一個頻繁處理的地方都適合在框架中完成。Python有一個很著名的Web框架,名叫bottle,整個框架由bottle.py一個檔案構成,共4400行,可以說是一個微框架。那麼理解這個微框架提供的特性,可以幫助我們理解框架的核心能力。

  • 路由(Routing):將請求對映到函式,支援動態路由。例如'/hello/:name
  • 模板(Templates):使用內建模板引擎提供模板渲染機制。
  • 工具集(Utilites):提供對 cookies,headers 等處理機制。
  • 外掛(Plugin):Bottle本身功能有限,但提供了外掛機制。可以選擇安裝到全域性,也可以只針對某幾個路由生效。
  • ...

Gee 框架

這個教程將使用 Go 語言實現一個簡單的 Web 框架,起名叫做Geegeektutu.com的前三個字母。我第一次接觸的 Go 語言的 Web 框架是GinGin的程式碼總共是14K,其中測試程式碼9K,也就是說實際程式碼量只有5K。Gin

也是我非常喜歡的一個框架,與Python中的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 - 極客兔