Golang http.RoundTripper 筆記

來源:互聯網
上載者:User
RoundTripper is an interface representing the ability to execute a single HTTP transaction, obtaining the Response for a given Request.

對於http用戶端,可以使用不同的實現了 RoundTripper 介面的Transport實現來配置它的行為

RoundTripper 有點像 http.Client 的中介軟體

介面定義

type RoundTripper interface {        RoundTrip(*Request) (*Response, error)}

需要實現RoundTrip函數

type SomeClient struct {}func (s *SomeClient) RoundTrip(r *http.Request)(*Response, error) {    //Something comes here...Maybe}

情境

原文: https://lanre.wtf/blog/2017/0...

  • 緩衝 responses,比如 app需要訪問 Github api,擷取 trending repos,這個資料變動不頻繁,假設30分鐘變動一次,你顯然不希望每次都要點擊api都要來請求Github api,解決這個問題的方法是實現這樣的http.RoundTripper

    • 有緩衝時從緩衝取出response資料
    • 到期,資料通過重新請求api擷取
  • 根據需要設定http header, 一個容易想到的例子go-github一個Github的 api的go用戶端。某些github api不需要認證,有些需要認證則需要提供自己的http client,比如 ghinstallation,下面是ghinstallation 的 RoundTrip 函數實現,設定 Authorization 頭

  • 限速(Rate limiting) 控制請求速率

實際的例子

實現http.RoundTripper 緩衝 http response的邏輯。

一個http server的實現

import (    "fmt"    "net/http")func main() {    // server/main.go    mux := http.NewServeMux()    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {        // This is here so we can actually see that the responses that have been cached don't get here        fmt.Println("The request actually got here")        w.Write([]byte("You got here"))    })    http.ListenAndServe(":8000", mux)}

http client中建立新的 http.Transport 實現 http.RoundTripper介面

主程式main實現
https://github.com/adelowo/ro...

func main() {    cachedTransport := newTransport()    // cachedTransport 是自訂實現http.RoundTripper介面的 Transport    client := &http.Client{        Transport: cachedTransport,        Timeout:   time.Second * 5,    }    // 每5秒清除緩衝    cacheClearTicker := time.NewTicker(time.Second * 5)    //每秒請求一次,可以看出response是從緩衝擷取還是從伺服器請求    reqTicker := time.NewTicker(time.Second * 1)    terminateChannel := make(chan os.Signal, 1)    signal.Notify(terminateChannel, syscall.SIGTERM, syscall.SIGHUP)    req, err := http.NewRequest(http.MethodGet, "http://localhost:8000", strings.NewReader(""))    if err != nil {        panic("Whoops")    }    for {        select {        case <-cacheClearTicker.C:            // Clear the cache so we can hit the original server            cachedTransport.Clear()        case <-terminateChannel:            cacheClearTicker.Stop()            reqTicker.Stop()            return        case <-reqTicker.C:            resp, err := client.Do(req)            if err != nil {                log.Printf("An error occurred.... %v", err)                continue            }            buf, err := ioutil.ReadAll(resp.Body)            if err != nil {                log.Printf("An error occurred.... %v", err)                continue            }            fmt.Printf("The body of the response is \"%s\" \n\n", string(buf))        }    }}

cacheTransport 中 RoundTrip 函數實現讀取緩衝中的reponse

func (c *cacheTransport) RoundTrip(r *http.Request) (*http.Response, error) {    // Check if we have the response cached..    // If yes, we don't have to hit the server    // We just return it as is from the cache store.    if val, err := c.Get(r); err == nil {        fmt.Println("Fetching the response from the cache")        return cachedResponse([]byte(val), r)    }    // Ok, we don't have the response cached, the store was probably cleared.    // Make the request to the server.    resp, err := c.originalTransport.RoundTrip(r)    if err != nil {        return nil, err    }    // Get the body of the response so we can save it in the cache for the next request.    buf, err := httputil.DumpResponse(resp, true)    if err != nil {        return nil, err    }    // Saving it to the cache store    c.Set(r, string(buf))    fmt.Println("Fetching the data from the real source")    return resp, nil}

運行結果

links:

  • https://lanre.wtf/blog/2017/0...
  • https://golang.org/pkg/net/ht...
  • https://www.jianshu.com/p/dd0...
  • https://github.com/linki/inst...
  • https://github.com/bradleyfal...
  • https://github.com/adelowo/ro...
  • https://gist.github.com/lidas...
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.