0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Go項(xiàng)目中引入中間件的目的和效果如何

阿銘linux ? 來源:思否開發(fā)者社區(qū) ? 作者:guyan0319 ? 2021-08-14 14:24 ? 次閱讀

中間件是什么?Go 項(xiàng)目中引入中間件的目的和效果如何?本文詳細(xì)介紹了Golang 中間件。

中間件是一種計(jì)算機(jī) 軟件,可為 操作系統(tǒng) 提供的 軟件應(yīng)用程序 提供服務(wù),以便于各個(gè)軟件之間的溝通,特別是系統(tǒng)軟件和應(yīng)用軟件。廣泛用于 web 應(yīng)用和面向服務(wù)的體系結(jié)構(gòu)等。

縱觀 GO 語言,中間件應(yīng)用比較普遍,主要應(yīng)用:

記錄對服務(wù)器發(fā)送的請求(request)

處理服務(wù)器響應(yīng)(response )

請求和處理之間做一個(gè)權(quán)限認(rèn)證工作

遠(yuǎn)程調(diào)用

安全

等等

中間件處理程序是簡單的http.Handler,它包裝另一個(gè)http.Handler做請求的一些預(yù)處理和/或后處理。它被稱為“中間件”,因?yàn)樗挥?Go Web 服務(wù)器和實(shí)際處理程序之間的中間位置。

下面是一些中間件例子

記錄日志中間件

package main

import (

“fmt”

“l(fā)og”

“net/http”

func logging(f http.HandlerFunc) http.HandlerFunc {

return func(w http.ResponseWriter, r *http.Request) {

log.Println(r.URL.Path)

f(w, r)

}

}

func foo(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “foo”)

}

func bar(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “bar”)

}

func main() {

http.HandleFunc(“/foo”, logging(foo))

http.HandleFunc(“/bar”, logging(bar))

http.ListenAndServe(“:8080”, nil)

}

訪問 http://localhost:8080/foo

返回結(jié)果

foo

將上面示例修改下,也可以實(shí)現(xiàn)相同的功能。

package main

import (

“fmt”

“l(fā)og”

“net/http”

func foo(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “foo”)

}

func bar(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “bar”)

}

func loggingMiddleware(next http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

log.Println(r.URL.Path)

next.ServeHTTP(w, r)

})

}

func main() {

http.Handle(“/foo”, loggingMiddleware(http.HandlerFunc(foo)))

http.Handle(“/bar”, loggingMiddleware(http.HandlerFunc(bar)))

http.ListenAndServe(“:8080”, nil)

}

訪問 http://localhost:8080/foo

返回結(jié)果

foo

多中間件例子

package main

import (

“fmt”

“l(fā)og”

“net/http”

time”

type Middleware func(http.HandlerFunc) http.HandlerFunc// Logging logs all requests with its path and the time it took to processfunc Logging() Middleware {

// Create a new Middleware

return func(f http.HandlerFunc) http.HandlerFunc {

// Define the http.HandlerFunc

return func(w http.ResponseWriter, r *http.Request) {

// Do middleware things

start := time.Now()

defer func() { log.Println(r.URL.Path, time.Since(start)) }()

// Call the next middleware/handler in chain

f(w, r)

}

}

}

// Method ensures that url can only be requested with a specific method, else returns a 400 Bad Requestfunc Method(m string) Middleware {

// Create a new Middleware

return func(f http.HandlerFunc) http.HandlerFunc {

// Define the http.HandlerFunc

return func(w http.ResponseWriter, r *http.Request) {

// Do middleware things

if r.Method != m {

http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)

return

}

// Call the next middleware/handler in chain

f(w, r)

}

}

}

// Chain applies middlewares to a http.HandlerFuncfunc Chain(f http.HandlerFunc, middlewares 。。.Middleware) http.HandlerFunc {

for _, m := range middlewares {

f = m(f)

}

return f

}

func Hello(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “hello world”)

}

func main() {

http.HandleFunc(“/”, Chain(Hello, Method(“GET”), Logging()))

http.ListenAndServe(“:8080”, nil)

}

中間件本身只是將其http.HandlerFunc作為其參數(shù)之一,包裝它并返回一個(gè)新http.HandlerFunc的服務(wù)器來調(diào)用。在這里,我們定義了一種新類型Middleware,最終可以更容易地將多個(gè)中間件鏈接在一起。

當(dāng)然我們也可以改成如下形式

package main

import (

“fmt”

“l(fā)og”

“net/http”

“time”

type Middleware func(http.Handler) http.Handlerfunc Hello(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “hello world”)

}

func Chain(f http.Handler, mmap 。。.Middleware) http.Handler {

for _, m := range mmap {

f = m(f)

}

return f

}

func Method(m string) Middleware {

return func(f http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

log.Println(r.URL.Path)

if r.Method != m {

http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)

return

}

f.ServeHTTP(w, r)

})

}

}

func Logging() Middleware {

return func(f http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

//log.Println(r.URL.Path)

// Do middleware things

start := time.Now()

defer func() { log.Println(r.URL.Path, time.Since(start)) }()

f.ServeHTTP(w, r)

})

}

}

func main() {

http.Handle(“/”, Chain(http.HandlerFunc(Hello), Method(“GET”), Logging()))

http.ListenAndServe(“:8080”, nil)

}

在 gin 框架下實(shí)現(xiàn)中間件

r := gin.Default() 創(chuàng)建帶有默認(rèn)中間件的路由,默認(rèn)是包含 logger 和 recovery 中間件的

r :=gin.new() 創(chuàng)建帶有沒有中間件的路由

示例

package main

import (

“github.com/gin-gonic/gin”

“l(fā)og”

“time”

func Logger() gin.HandlerFunc {

return func(c *gin.Context) {

t := time.Now()

// Set example variable

c.Set(“example”, “12345”)

// before request

c.Next()

// after request

latency := time.Since(t)

log.Print(latency) //時(shí)間 0s

// access the status we are sending

status := c.Writer.Status()

log.Println(status) //狀態(tài) 200

}

}

func main() {

r := gin.New()

r.Use(Logger())

r.GET(“/test”, func(c *gin.Context) {

example := c.MustGet(“example”)。(string)

// it would print: “12345”

log.Println(example)

})

// Listen and serve on 0.0.0.0:8080

r.Run(“:8080”)

}

以上示例也可改為

package main

import (

“github.com/gin-gonic/gin”

“l(fā)og”

“time”

func Logger() gin.HandlerFunc {

return func(c *gin.Context) {

t := time.Now()

// Set example variable

c.Set(“example”, “12345”)

// before request

c.Next()

// after request

latency := time.Since(t)

log.Print(latency) //時(shí)間 0s

// access the status we are sending

status := c.Writer.Status()

log.Println(status) //狀態(tài) 200

}

}

func main() {

r := gin.New()

r.GET(“/test”, Logger(), func(c *gin.Context) {

example := c.MustGet(“example”)。(string)

// it would print: “12345”

log.Println(example)

})

// Listen and serve on 0.0.0.0:8080

r.Run(“:8080”)

}

即不用 r.use 添加中間件,直接將 Logger() 寫到 r.GET 方法的參數(shù)里(“/test”之后)。

更多 gin 中間件示例可參考 https://github.com/gin-gonic/gin

轉(zhuǎn)自:guyan0319

segmentfault.com/a/1190000018819804

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Web
    Web
    +關(guān)注

    關(guān)注

    2

    文章

    1255

    瀏覽量

    69292
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7360

    瀏覽量

    87632
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8958

    瀏覽量

    85081

原文標(biāo)題:GO 中間件 Middleware

文章出處:【微信號:aming_linux,微信公眾號:阿銘linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    中間件全球數(shù)據(jù)實(shí)時(shí)同步利器,華為云 EventGrid 事件流重磅發(fā)布

    【摘要】 華為云 EventGrid 事件流(簡稱 EG)作為易用、穩(wěn)定、高效的數(shù)據(jù)同步管道連接不同的系統(tǒng)與服務(wù),支持中間件數(shù)據(jù)在線實(shí)時(shí)同步。事件流圍繞云中間件,降低了中間件之間數(shù)據(jù)流通的復(fù)雜性
    的頭像 發(fā)表于 10-31 18:39 ?200次閱讀
    <b class='flag-5'>中間件</b>全球數(shù)據(jù)實(shí)時(shí)同步利器,華為云 EventGrid 事件流重磅發(fā)布

    北京靈奧科技基于亞馬遜云科技打造大模型中間件

    助力企業(yè)加速應(yīng)用生成式AI 北京2024年6月27日?/美通社/ --?北京靈奧科技基于亞馬遜云科技的生成式AI、數(shù)據(jù)庫和容器等云服務(wù),打造大模型中間件,將基礎(chǔ)模型優(yōu)勢和企業(yè)業(yè)務(wù)數(shù)據(jù)無縫結(jié)合,打通
    的頭像 發(fā)表于 06-27 21:21 ?516次閱讀

    一文掌握中間件技術(shù)基礎(chǔ)

    ? 中間件(MiddleWare)是提供系統(tǒng)軟件和應(yīng)用軟件之間連接的軟件,以便于軟件各部件之間的溝通,特別是應(yīng)用軟件對于系統(tǒng)軟件的集中的邏輯,在現(xiàn)代信息技術(shù)應(yīng)用框架如Web服務(wù)、面向服務(wù)的體系結(jié)構(gòu)等中應(yīng)用比較廣泛。
    的頭像 發(fā)表于 04-23 14:45 ?390次閱讀
    一文掌握<b class='flag-5'>中間件</b>技術(shù)基礎(chǔ)

    求助,關(guān)于MDK5中間件network庫靜態(tài)ip手動(dòng)配置問題

    最近在研究MDK5的自帶的Middleware中間件庫,其中用到NetWork庫,ipv4及ipv6各項(xiàng)功能均已調(diào)通。發(fā)現(xiàn)MDK提供的network庫并沒有提供供用戶手動(dòng)修改設(shè)備Ip地址及mac地址
    發(fā)表于 04-22 08:09

    中間件廠商中創(chuàng)股份科創(chuàng)板上市

    山東中創(chuàng)軟件商用中間件股份有限公司(以下簡稱“中創(chuàng)股份”)成功在上交所科創(chuàng)板上市,這標(biāo)志著這家國內(nèi)領(lǐng)先的基礎(chǔ)軟件中間件產(chǎn)品與服務(wù)提供商邁入了新的發(fā)展階段。中創(chuàng)股份在國民經(jīng)濟(jì)重點(diǎn)行業(yè)領(lǐng)域,如金融、能源、交通等,擁有廣泛的業(yè)務(wù)布局和深厚的技術(shù)積累。
    的頭像 發(fā)表于 03-18 17:29 ?768次閱讀

    華玉通軟宣布“海鷗”確定性調(diào)度中間件(SEAGULL DS)正式商用

    今天,華玉通軟(下稱“華玉”)宣布“海鷗”確定性調(diào)度中間件(SEAGULL DS)正式商用。
    的頭像 發(fā)表于 03-17 11:01 ?591次閱讀
    華玉通軟宣布“海鷗”確定性調(diào)度<b class='flag-5'>中間件</b>(SEAGULL DS)正式商用

    中創(chuàng)股份成功登陸科創(chuàng)板,引領(lǐng)中間件技術(shù)創(chuàng)新

    山東中創(chuàng)軟件商用中間件股份有限公司(簡稱“中創(chuàng)股份”)近日在科創(chuàng)板成功上市,標(biāo)志著其在國內(nèi)基礎(chǔ)軟件中間件領(lǐng)域的領(lǐng)先地位得到資本市場認(rèn)可。
    的頭像 發(fā)表于 03-15 17:39 ?773次閱讀

    中間件廠商中創(chuàng)股份成功上市

    近日,國內(nèi)領(lǐng)先的基礎(chǔ)軟件中間件產(chǎn)品與服務(wù)提供商——山東中創(chuàng)軟件商用中間件股份有限公司(以下簡稱“中創(chuàng)股份”)在上海證券交易所科創(chuàng)板上市,股票代碼為“688695”。這一里程碑事件標(biāo)志著中創(chuàng)股份在基礎(chǔ)軟件中間件領(lǐng)域的實(shí)力和影響力得
    的頭像 發(fā)表于 03-14 15:25 ?812次閱讀

    中創(chuàng)股份成功登陸科創(chuàng)板,深耕中間件行業(yè)

    3月13日,山東中創(chuàng)軟件商用中間件股份有限公司(以下簡稱“中創(chuàng)股份”)在上海證券交易所科創(chuàng)板成功掛牌上市,標(biāo)志著這家在中間件領(lǐng)域深耕二十余年的企業(yè)迎來了新的發(fā)展篇章。
    的頭像 發(fā)表于 03-13 15:42 ?573次閱讀

    基礎(chǔ)軟件中間件產(chǎn)品與服務(wù)提供商中創(chuàng)股份成功上市

    山東中創(chuàng)軟件商用中間件股份有限公司(股票簡稱:中創(chuàng)股份,股票代碼:688695)今日在上海證券交易所科創(chuàng)板成功上市,開啟了公司發(fā)展的新篇章。作為中間件技術(shù)標(biāo)準(zhǔn)的主要推動(dòng)者和制定者,中創(chuàng)股份在中間件
    的頭像 發(fā)表于 03-13 14:21 ?633次閱讀

    中創(chuàng)股份科創(chuàng)板成功上市,引領(lǐng)中間件技術(shù)新篇章

    中間件產(chǎn)品與服務(wù)提供商中創(chuàng)股份近日在上交所科創(chuàng)板成功掛牌上市,這一里程碑事件標(biāo)志著中創(chuàng)股份在基礎(chǔ)軟件中間件領(lǐng)域的領(lǐng)先地位得到了市場的廣泛認(rèn)可,并為其未來發(fā)展打開了新的篇章。
    的頭像 發(fā)表于 03-13 14:13 ?596次閱讀

    國產(chǎn)中間件提供商中創(chuàng)股份上市

    近日,國內(nèi)中間件領(lǐng)域的領(lǐng)軍企業(yè)——山東中創(chuàng)軟件商用中間件股份有限公司(簡稱“中創(chuàng)股份”)在科創(chuàng)板成功上市,這一重要事件標(biāo)志著中創(chuàng)股份在中間件行業(yè)深耕多年后,迎來了嶄新的發(fā)展階段。
    的頭像 發(fā)表于 03-13 13:49 ?552次閱讀

    Redis可以實(shí)現(xiàn)消息中間件MQ的功能

    是一種通信模式:發(fā)送者(PUBLISH)發(fā)送消息,訂閱者(SUBSCRIBE)接收消息,可以實(shí)現(xiàn)進(jìn)程間的消息傳遞   Redis可以實(shí)現(xiàn)消息中間件MQ的功能,通過發(fā)布訂閱實(shí)現(xiàn)消息的引導(dǎo)和分流
    的頭像 發(fā)表于 01-25 14:48 ?859次閱讀
    Redis可以實(shí)現(xiàn)消息<b class='flag-5'>中間件</b>MQ的功能

    Ai-WB2-12F使用安信可中間件接入愛星云,遠(yuǎn)程點(diǎn)個(gè)燈(2)

    上次已經(jīng)給大家講了如何搭建中間件SDK(Ai-WB2-12F使用安信可中間件接入愛星云,遠(yuǎn)程點(diǎn)個(gè)燈——第一篇)。經(jīng)過上次的帖子,小伙伴們想必已經(jīng)完成一個(gè)新項(xiàng)目的添加,并使用WB2編譯成功,今天講
    的頭像 發(fā)表于 01-08 17:18 ?589次閱讀
    Ai-WB2-12F使用安信可<b class='flag-5'>中間件</b>接入愛星云,遠(yuǎn)程點(diǎn)個(gè)燈(2)

    oracle數(shù)據(jù)庫中間件有哪些

    Oracle數(shù)據(jù)庫中間件是指由Oracle公司開發(fā)和提供的一系列軟件產(chǎn)品,用于構(gòu)建、部署和管理企業(yè)級應(yīng)用。它提供了一套完整的解決方案,包括數(shù)據(jù)庫管理、應(yīng)用服務(wù)器、數(shù)據(jù)集成和開發(fā)工具等,為企業(yè)提供高效
    的頭像 發(fā)表于 12-05 16:17 ?1765次閱讀