Skip to content

Instantly share code, notes, and snippets.

@aleics
Created March 22, 2016 15:37
Show Gist options
  • Save aleics/4cba176008ec411d3a39 to your computer and use it in GitHub Desktop.
Save aleics/4cba176008ec411d3a39 to your computer and use it in GitHub Desktop.
// gist saved for future use
// practice code of the decorator pattern for http requests
// extracted from the talk of Tomas Senart (http://bit.ly/22tUcl4)
package main
import (
"log"
"net/http"
"os"
)
type Client interface {
Do(*http.Request) (*http.Response, error)
}
// ClientFunc is a function type that implements the Client interface.
type ClientFunc func(*http.Request) (*http.Response, error)
func (f ClientFunc) Do(r *http.Request) (*http.Response, error) {
return f(r)
}
// A Decorator wraps a Client with extra behaviour
type Decorator func(c Client) Client
// Logging returns a Decorator that logs a Client's requests
func Logging(l *log.Logger) Decorator {
return func(c Client) Client {
return ClientFunc(func(r *http.Request) (*http.Response, error) {
l.Printf("%s: %s %s", r.UserAgent, r.Method, r.URL)
return c.Do(r)
})
}
}
// Decorate decorates a Client c with all the given Decorators, in order.
func Decorate(c Client, ds ...Decorator) Client {
decorated := c
for _, decorate := range ds {
decorated = decorate(decorated)
}
return decorated
}
func main() {
cli := Decorate(http.DefaultClient,
Logging(log.New(os.Stdout, "client: ", log.LstdFlags)),
)
req, err := http.NewRequest("GET", "www.google.com", nil)
if err != nil {
panic(err)
}
cli.Do(req)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment