2016-09-16 16 views
2

我想問一下,我們是否可以爲Go http客戶端創建'中間件'功能?示例我想添加一個日誌函數,因此每個發送的請求都會被記錄下來,或者添加setAuthToken,以便將令牌添加到每個請求的標題中。Go http客戶端是否有'中間件'?

回答

5

您可以使用HTTP客戶端Transport參數到效果,與構圖模式,使用的事實是:

  • http.Client.Transport定義了處理所有HTTP請求的函數;
  • http.Client.Transport具有接口類型http.RoundTripper,因此可以用您自己的實現來替換;

例如:

package main 

import (
    "fmt" 
    "net/http" 
) 

// This type implements the http.RoundTripper interface 
type LoggingRoundTripper struct { 
    Proxied http.RoundTripper 
} 

func (lrt LoggingRoundTripper) RoundTrip(req *http.Request) (res *http.Response, e error) { 
    // Do "before sending requests" actions here. 
    fmt.Printf("Sending request to %v\n", req.URL) 

    // Send the request, get the response (or the error) 
    res, e = lrt.Proxied.RoundTrip(req) 

    // Handle the result. 
    if (e != nil) { 
     fmt.Printf("Error: %v", e) 
    } else { 
     fmt.Printf("Received %v response\n", res.Status) 
    } 

    return 
} 

func main() { 
    var c = &http.Client{Transport:LoggingRoundTripper{http.DefaultTransport}} 
    c.Get("https://www.google.com") 
} 

隨意更改名稱,你想,我沒想到他們很長時間。

0

這可以通過使用閉包函數來實現。這也可能是用一個例子更加清晰:

package main 

import ( 
    "fmt" 
    "net/http" 
) 

func main() { 
    http.HandleFunc("/hello", logged(hello)) 
    http.ListenAndServe(":3000", nil) 
} 

func logged(f func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) { 
    return func(w http.ResponseWriter, r *http.Request) { 
    fmt.Println("logging something") 
    f(w, r) 
    fmt.Println("finished handling request") 
    } 
} 

func hello(w http.ResponseWriter, r *http.Request) { 
    fmt.Fprintln(w, "<h1>Hello!</h1>") 
} 

歸功於:http://www.calhoun.io/5-useful-ways-to-use-closures-in-go/

+0

謝謝。但是,當我們發送請求 – quangpn88

+0

時,我想要的對於http客戶端來說也是一樣的。這並沒有回答這個問題 - 它是在服務HTTP時執行中間件的一種方式,而不是在請求它時。 –

+0

糟糕,我沒有花時間理解你的問題。對於客戶端來說,類似的東西絕對是可能的。我會看看我是否可以在當天晚些時候舉一個例子:) – Bugless