Gin-Gonic 框架中間件原理與應(yīng)用

在 Go 的世界里, web 框架簡直多如牛毛.

前有自帶電池的標(biāo)準(zhǔn)庫(net/http), 后有簡潔優(yōu)雅的 Gin-Gonic(以下簡稱 Gin), 再有全棧開發(fā)一枝花 Beego, 等等不可勝數(shù).

使用 Go 有一段時(shí)間了, web 開發(fā)一直用的 Gin. Gin 的思想和 Python 框架 Flask 有頗多相似之處, 可以稱作 微框架 .

Gin 包括以下幾個(gè)主要的部分:

  • 設(shè)計(jì)精巧的路由/中間件系統(tǒng);
  • 簡單好用的核心上下文 Context;
  • 附贈(zèng)工具集(JSON/XML 響應(yīng), 數(shù)據(jù)綁定與校驗(yàn)等).

本文意在探究 Gin 中間件的執(zhí)行原理. 我們先看如下的 Hello World 版 Gin 程序:

import (
 "log"
 "net/http"

 "github.com/gin-gonic/gin"
)

func main() {
 r := gin.Default()

 r.GET("/ping", func(c *gin.Context) {
 c.String(http.StatusOK, "%s", "pong!")
 })

 if err := r.Run("0.0.0.0:8080"); err != nil {
 log.Fatalln(err)
 }
}

這個(gè)簡單的 Gin 程序默認(rèn)啟用了兩個(gè)中間件, 分別是 Logger() 和 Recovery(), Context 是 Gin 的核心, 它的構(gòu)造如下:

type Context struct {
 writermem responseWriter
 Request   *http.Request
 Writer    ResponseWriter

 Params   Params
 handlers HandlersChain
 index    int8

 engine   *Engine
 Keys     map[string]interface{}
 Errors   errorMsgs
 Accepted []string
}

其中 handlers 我們通過源碼可以知道就是 []HandlerFunc. 而它的簽名正是:

type HandlerFunc func(*Context)

所以中間件和我們普通的 HandlerFunc 沒有任何區(qū)別對吧, 我們怎么寫 HandlerFunc 就可以怎么寫一個(gè)中間件. 那么問題來了, 我們怎么解決一個(gè)請求和一個(gè)響應(yīng)經(jīng)過我們的中間件呢? 我們來寫個(gè)簡單的中間件分析一下:

r.Use(func(c *gin.Context) {
 log.Println("Request in") // ①
 c.Next() // next handler func
 log.Println("Response out") // ②
})

神奇的語句出現(xiàn)了, 沒錯(cuò)就是 c.Next(), 所有中間件都有 Request 和 Response 的分水嶺, 就是這個(gè) c.Next(), 否則沒有辦法傳遞中間件. 我們來看源碼:

func (c *Context) Next() {
 c.index++
 s := int8(len(c.handlers))
 for ; c.index < s; c.index++ {
 c.handlers[c.index](c)
 }
}

一個(gè)請求過來, Gin 會(huì)主動(dòng)調(diào)用 c.Next() 一次. 因?yàn)?handlers 是 slice , 所以后來者中間件會(huì)追加到尾部. 這樣就形成了形如 m1(m2(f())) 的調(diào)用鏈. 正如上面數(shù)字① ② 標(biāo)注的一樣, 我們會(huì)依次執(zhí)行如下的調(diào)用:

m1① -> m2① -> f -> m2② -> m1②

我們用下面一張圖來來總結(jié)這種關(guān)系:


本文來自:lingchao.xin

感謝作者:lingchao

查看原文:Gin-Gonic 框架中間件原理與應(yīng)用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)發(fā)自:http://shanshanpt.github.io/2016/05/03/go-gin.html gi...
    dncmn閱讀 6,194評論 0 1
  • 最近公司要求更新自研框架,就順便看了一下gonic的框架實(shí)現(xiàn),代碼不多,感覺主要有兩個(gè)特點(diǎn),第一個(gè)httprout...
    pysta閱讀 649評論 0 0
  • 所謂框架 框架一直是敏捷開發(fā)中的利器,能讓開發(fā)者很快的上手并做出應(yīng)用,甚至有的時(shí)候,脫離了框架,一些開發(fā)者都不會(huì)寫...
    人世間閱讀 217,050評論 11 242
  • 2016.10.06 中國vs敘利亞 國足輸了 0:1 賽前 國足輸贏我不敢預(yù)料 但是 輸?shù)舯荣惡?網(wǎng)絡(luò)上的語言暴...
    __幻想生活閱讀 163評論 1 1
  • 馬志忠,教語文。聲音洪亮,課講得好。今天坐在窗臺(tái)底下,滿頭白發(fā)越發(fā)蒼白。人老起來比啥都快,而且人奔老就像百米線上的...
    想看看大千世界閱讀 282評論 0 0

友情鏈接更多精彩內(nèi)容