在 Golang 中實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Http中間件過(guò)程詳解
本文主要針對(duì)Golang的內(nèi)置庫(kù) net/http 做了簡(jiǎn)單的擴(kuò)展,通過(guò)添加中間件的形式實(shí)現(xiàn)了管道(Pipeline)模式,這樣的好處是各模塊之間是低耦合的,符合單一職責(zé)原則,可以很靈活的通過(guò)中間件的形式添加一些功能到管道中,一次請(qǐng)求和響應(yīng)在管道中的執(zhí)行過(guò)程如下
首先, 我定義了三個(gè)測(cè)試的中間件 Middleware1,2,3 如下
func Middleware1(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Println("M1 in") next.ServeHTTP(w, r) fmt.Println("M1 out") }) } func Middleware2(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Println("M2 in") next.ServeHTTP(w, r) fmt.Println("M2 out") }) } func Middleware3(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Println("M3 in") next.ServeHTTP(w, r) fmt.Println("M3 out") }) }
這里中間件的入?yún)⒑统鰠⒌念?lèi)型都是 http.Handler, 然后在 next.ServeHTTP() 的前后分別輸出了 In 和 Out.
接下來(lái),定義一個(gè) Pipeline 的方法,里面使用嵌套的形式, 使用了上面定義的三個(gè)測(cè)試的中間件.
func Pipeline(next http.Handler) http.Handler { return Middleware1(Middleware2(Middleware3(next))) }
然后還需要業(yè)務(wù)代碼,這里我定義了 LoginHandler 和 RegisterHandler 兩個(gè)方法
func LoginHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("Login...") w.Write([]byte("Login...")) } func RegisterHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("Register...") w.Write([]byte("Register...")) }
最后修改程序的 main 函數(shù), 在 Login 接口上使用上面添加過(guò)中間件的 Pipeline
func main() { http.Handle("/Login", Pipeline(http.HandlerFunc(LoginHandler))) http.Handle("/Register", http.HandlerFunc(RegisterHandler)) http.ListenAndServe(":8080", nil) }
啟動(dòng)程序后,訪問(wèn) http://localhost:8080/Login, 程序的輸出如下,這和本文最上面的管道的流程圖是一致的,然后訪問(wèn) Register 接口, 控制臺(tái)沒(méi)有輸出信息,當(dāng)然也不會(huì)執(zhí)行任何中間件。
現(xiàn)在已經(jīng)實(shí)現(xiàn)了中間件的機(jī)制,但是,上面添加中間件是用嵌套的方法,這種方式不能說(shuō)不太優(yōu)雅,只能說(shuō)非常的Low,接下來(lái)我們需要對(duì)管道進(jìn)行優(yōu)化
type Chain struct { middlewares []func(handler http.Handler) http.Handler } func Pipeline(next http.Handler) http.Handler { //return Middleware1(Middleware2(Middleware3(next))) return AddMiddlewares(Middleware1,Middleware2,Middleware3).Then(next) } func AddMiddlewares(m ...func(handlerFunc http.Handler) http.Handler) Chain { c := Chain{} c.middlewares = append(c.middlewares,m...) return c } func (c Chain) Then(next http.Handler) http.Handler { for i := range c.middlewares { prev := c.middlewares[len(c.middlewares)-1-i] next = prev(next) } return next }
首先定義了一個(gè)Chain 的struct,用來(lái)接收添加到管道中的中間件,在 AddMiddlewares() 函數(shù)中,接收了多個(gè)Handle, 然后組裝到 Chain 對(duì)象并返回, 接下來(lái)調(diào)用 Then() 函數(shù), 把管道中的中間件和業(yè)務(wù)的Handler 關(guān)聯(lián)起來(lái)。在中間件的使用方式上, 這兩種方法都是一樣的,只需要調(diào)用 Pipeline() 方法就行了。
本文在go web中簡(jiǎn)單的實(shí)現(xiàn)了中間件的機(jī)制,這樣帶來(lái)的好處也是顯而易見(jiàn)的,當(dāng)然社區(qū)也有一些成熟的 middleware 組件,包括 Gin 一些Web框架中也包含了 middleware 相關(guān)的功能, 希望對(duì)您有用.
到此這篇關(guān)于在 Golang 中實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Http中間件的文章就介紹到這了,更多相關(guān)Golang Http中間件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一文詳解Golang協(xié)程調(diào)度器scheduler
這篇文章主要介紹了一文詳解Golang協(xié)程調(diào)度器scheduler,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07Golang中優(yōu)秀的消息隊(duì)列NSQ基礎(chǔ)安裝及使用詳解
這篇文章主要介紹了Golang中優(yōu)秀的消息隊(duì)列NSQ基礎(chǔ)安裝及使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Golang實(shí)現(xiàn)Redis網(wǎng)絡(luò)協(xié)議實(shí)例探究
這篇文章主要為大家介紹了Golang實(shí)現(xiàn)Redis網(wǎng)絡(luò)協(xié)議實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01go語(yǔ)言切片slice使用細(xì)節(jié)和注意事項(xiàng)整理大全
這篇文章主要給大家介紹了關(guān)于go語(yǔ)言切片slice使用細(xì)節(jié)和注意事項(xiàng)整理的相關(guān)資料,需要的朋友可以參考下2024-05-05Golang 函數(shù)執(zhí)行時(shí)間統(tǒng)計(jì)裝飾器的一個(gè)實(shí)現(xiàn)詳解
這篇文章主要介紹了Golang 函數(shù)執(zhí)行時(shí)間統(tǒng)計(jì)裝飾器的一個(gè)實(shí)現(xiàn)詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03golang中拿slice當(dāng)queue和拿list當(dāng)queue使用分析
這篇文章主要為大家介紹了golang?中拿slice當(dāng)queue和拿list當(dāng)queue使用分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Windows下使用go語(yǔ)言寫(xiě)程序安裝配置實(shí)例
這篇文章主要介紹了Windows下使用go語(yǔ)言寫(xiě)程序安裝配置實(shí)例,本文講解了安裝go語(yǔ)言、寫(xiě)go代碼、生成可執(zhí)行文件、批量生成可執(zhí)行文件等內(nèi)容,需要的朋友可以參考下2015-03-03golang中time包之時(shí)間間隔格式化和秒、毫秒、納秒等時(shí)間戳格式輸出的方法實(shí)例
時(shí)間和日期是我們編程中經(jīng)常會(huì)用到的,下面這篇文章主要給大家介紹了關(guān)于golang中time包之時(shí)間間隔格式化和秒、毫秒、納秒等時(shí)間戳格式輸出的方法實(shí)例,需要的朋友可以參考下2022-08-08