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
RoundTripper
A 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 ...