這個(gè)過程中會(huì)閱讀并參考一些其" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > Go學(xué)習(xí)筆記 試著做一個(gè)Web框架

Go學(xué)習(xí)筆記 試著做一個(gè)Web框架

時(shí)間:2023-07-05 14:48:01 | 來源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-07-05 14:48:01 來源:網(wǎng)站運(yùn)營(yíng)

Go學(xué)習(xí)筆記 試著做一個(gè)Web框架:Go語言的Web框架有非常多,在日常開發(fā)中使用的有: beego、gin、revel等。這些框架也是一部分初學(xué)者的起點(diǎn),這個(gè)系列的文章將會(huì)記錄一個(gè)Web框架的開發(fā)歷程。

這個(gè)過程中會(huì)閱讀并參考一些其他的開源框架并形成自己的代碼,后續(xù)的文章大概也是這個(gè)節(jié)奏,不斷完善框架。

完整代碼:

最簡(jiǎn)單的HTTP Server

先從最簡(jiǎn)單最原始的開始入手,在Go語言中需要一點(diǎn)簡(jiǎn)單的代碼就可以生成一個(gè)Server,如下:

package mainimport ( "net/http")func main() { http.HandleFunc("/ping", pingHandlerFunc) http.ListenAndServe(":9527", nil)}func pingHandlerFunc(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong"))}這里發(fā)現(xiàn)有三個(gè)點(diǎn),一個(gè)是main函數(shù)中的http.HandleFunc方法,另一個(gè)是http.ListenAndServe,最后是pingHandlerFunc。

其中handler func是Router功能的一部分,從中我們可以設(shè)計(jì)出大致的樣子。下文會(huì)詳細(xì)描述這些組件。

Router

Router是實(shí)現(xiàn)路由選擇、路由解析等功能。當(dāng)請(qǐng)求到達(dá)時(shí)正確地路由至指定的handher。

如果你看過gin或者beego中的Router實(shí)現(xiàn),它們通常采用樹的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)。

例如echo框架中的Router(router.go)就有明顯的特征:

type ( // Router is the registry of all registered routes for an `Echo` instance for // request matching and URL path parameter parsing. Router struct { tree *node routes map[string]*Route echo *Echo } node struct { //省略了node的內(nèi)容 } kind uint8 children []*node methodHandler struct { //這里是存放不同method的handler func的,省略一些內(nèi)容 get HandlerFunc })因?yàn)橐婚_始并不想搞得太復(fù)雜,這里暫時(shí)使用slice來保存。

type Router struct { // 路由表 Handlers []*RouterMapping}pattern與handler func存在著映射關(guān)系(路由表),這里可以用map的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ),在這里使用一個(gè)struct來作為Entity來保存映射的關(guān)系。

type RouterMapping struct { Pattern string HandlerFunc RequestHandler}Handler Func

go中handler func比較簡(jiǎn)單,我們需要再“裹上一層”(Context),這樣就可以從Writer和Request中擴(kuò)展更多功能。

這個(gè)設(shè)計(jì)在一些Web Framework中也是常見操作,這里放一些源碼的鏈接:

  1. echo - context.go
  2. gin - context.go
  3. beego - context.go
這是放出gin中Context片段

// Context is the most important part of gin. It allows us to pass variables between middleware,// manage the flow, validate the JSON of a request and render a JSON response for example.type Context struct { Request *http.Request Writer ResponseWriter}Context的生存周期通常貫穿整個(gè)請(qǐng)求-響應(yīng)的過程。

如法炮制,將Writer和Request放在一個(gè)struct (即Context)中。

type Context struct { Writer http.ResponseWriter Request *http.Request}定義一個(gè)type,這是用戶需要實(shí)現(xiàn)的Handler Func

type RequestHandler func(context *Context)到目前,我們已經(jīng)將go的Handler Func包裝完成。

Engine

engine是Web框架的入口。使用一個(gè)struct來保存類似:全局配置、一些子組件的入口,例如:Router、Render等。

在gin中,Engine的源碼(gin.go)是這樣的(省略了部分代碼):

type Engine struct { delims render.Delims HTMLRender render.HTMLRender FuncMap template.FuncMap trees methodTrees maxParams uint16}按照設(shè)計(jì)的思路,編寫代碼:

type Engine struct { Router *Router}添加RunAndListen方法,這里需要將之Router中的路由表項(xiàng)(Handlers)進(jìn)行注冊(cè)。

func (e *Engine) RunAndListen(addr string) { for _, handler := range e.Router.Handlers { http.HandleFunc(handler.Pattern, func(writer http.ResponseWriter, request *http.Request) { handler.HandlerFunc(&Context{ Writer: writer, Request: request, }) }) } log.Fatal(http.ListenAndServe(addr, nil))}測(cè)試一下:

func TestRunAndListen() { e := NewEngine() e.Router.AddHandler("/ping", func(context *Context) { data := map[string]interface{}{ "say":"pong", } rawData,err := json.Marshal(data) if err != nil { panic(err) } context.Writer.Header().Set("Content-Type","application/json") context.Writer.Write(rawData) }) e.RunAndListen(":8090")}訪問 http://localhost:8090/ping就能看到

{ "say": "pong"}

關(guān)鍵詞:學(xué)習(xí),筆記

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉