您好,登錄后才能下訂單哦!
這篇文章主要講解了“Golang的中間件設計模式怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Golang的中間件設計模式怎么實現”吧!
所以接下來我們就來看看demo吧 首先先定義好中間件的類型,這里我就簡單定義為以下的格式
type middleware func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error)
ctx: 協程間通信帶著
req: 請求的格式,這里圖簡便,直接interface{}類型
resp: 同req
err: error
handler: endpoint類型,真正用來發起請求的一個處理方法或者是經過N層中間件包裝的后的發起請求的處理方法
type endpoint func(ctx context.Context, req interface{}) (resp interface{}, err error) //ctx: 協程間通信帶著 //req: 請求的格式,這里圖簡便,直接interface{}類型 //resp: 同req //err: error
然后既然我們要將上方的endpoint
進行包裝然后產生一個新的endpoint
那么也就是需要一個函數去做一步的事情,input是endpoint
,ouput也是endpoint
type warp func(endpoint) endpoint //就是這個warp函數
然后我們通過每次調用這個warp的定義去生成一個新的endpoint
就可以產生一個類似于dfs鏈式調用的一個中間件的過程,因為將會一層套一層的endpoint
下去,然后當最后一層有返回了以后就可以接著返回了,然后不斷的彈棧回去最開始的地方,因為我們中間件的實現必然是要調用handler的
func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before1\n") resp, err = handler(ctx, req) fmt.Printf("end1\n") return }
// handler0 var handler endpoint = func(ctx context.Context, req interface{}) (resp interface{}, err error) { fmt.Printf("make msg\n") return nil, nil } // middleware var md Middleware = func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before1\n") resp, err = handler(ctx, req) fmt.Printf("end1\n") return } // warp ->> handler1 handler = warp(func(e endpoint) endpoint { return func(ctx context.Context, req interface{}) (resp interface{}, err error) { return md(ctx, req, e) } })(handler)
package main import ( "context" "fmt" ) type endpoint func(ctx context.Context, req interface{}) (resp interface{}, err error) type middleware func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) type warp func(endpoint) endpoint func main() { mds := []middleware{} mds = append(mds, func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before1\n") resp, err = handler(ctx, req) fmt.Printf("end1\n") return }) mds = append(mds, func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before2\n") resp, err = handler(ctx, req) fmt.Printf("end2\n") return }) var handler endpoint = func(ctx context.Context, req interface{}) (resp interface{}, err error) { fmt.Printf("make msg\n") return nil, nil } for i := len(mds) - 1; i >= 0; i-- { handler = warp(func(e endpoint) endpoint { // 由于go的機制問題如果不用tmp去存下當前的i,那么mds[i]就會取最終的那一個,就會溢出,所以在return前先保存一下i的量,然后每一個stack去存的變量就是對的 cur := i return func(ctx context.Context, req interface{}) (resp interface{}, err error) { return mds[cur](ctx, req, e) } })(handler) } resp, err := handler(context.Background(), "ster") if resp != nil && err != nil { return } }
結果是
before1
before2
make msg
end2
end1
結論:感覺有函數指針的語言都可以用這一套去實現一個中間件
感謝各位的閱讀,以上就是“Golang的中間件設計模式怎么實現”的內容了,經過本文的學習后,相信大家對Golang的中間件設計模式怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。