Golang http. Roundtripper notes

Source: Internet
Author: User
Roundtripper is an interface representing the ability to execute a single HTTP transaction obtaining the Response F or a given Request.

For an HTTP client, you can RoundTripper configure its behavior with different implementations of the implementation of the interface Transport

RoundTripperA bit like http.Client the middleware

Interface definition

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

Need to implement the roundtrip function

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

Scene

Original: https://lanre.wtf/blog/2017/0 ...

    • Cache responses, such as the app needs to access the GitHub API, get trending repos, this data changes infrequently, assuming 30 minutes to change once, you obviously do not want to click the API every time to request the Github API, The way to solve this problem is to achieve such ahttp.RoundTripper

      • Response data is fetched from cache when cached
      • Expires, data is retrieved by re-requesting the API
    • Set the HTTP header as needed, an easy-to-think example go-github a GitHub API to the go client. Some GitHub APIs do not require authentication, some require authentication to provide their own HTTP client, such as Ghinstallation, the following is ghinstallation roundtrip function implementation, set Authorization header

    • Speed limit (rate limiting) control request rates

The actual example

Implements http.RoundTripper the logic for caching HTTP response.

An implementation of an 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)}

Creating a new http.Transport implementation interface in the HTTP client http.RoundTripper

Main program Master Implementation
Https://github.com/adelowo/ro ...

Func Main () {cachedtransport: = Newtransport ()///Cachedtransport is a custom implementation of HTTP. Transport Client for Roundtripper interface: = &http. client{Transport:cachedtransport, Timeout:time. Second * 5,}//Every 5 seconds clear cache Cacheclearticker: = time. Newticker (time. Second * 5)//per second, you can see whether response is fetching from the cache or requesting reqticker from the server: = 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 <-term InateChannel: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", String (BUF))}}}

Cachetransport in roundtrip function to read reponse in cache

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}

Run results

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 ...
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.