http://andyrees.github.io/2015/your-code-a-mess-maybe-its-time-to-bring-in-the-decorators/
Your Code a Mess? Maybe it’s time to bring in the Decorators
How to apply decorators to Go code with two simple examples
Decorators in Go
In computer science a decorator is pattern for adding functionality (i.e. logging, authentication) to another function by wrapping it.
This is really useful for web handlers, but is also poorly documented in Go and has resulted in a miriad of middleware libraries being created, which, in my humble opinion, tend to be overkill for such a simple requirement.
In any language you should never wander far from the standard library, if the situation doesn’t warrant it and you should always avoid re-inventing the wheel.
It is so simple to decorate functions in Python, I couldn’t believe that it would be so difficult to replicate this functionality in Go.
After ardous hours of googling I found a great example by Alex Alehano, that shows the most concise example, can be easily applied to http handlers in GO and this is the result.
Decorating a simple function Example
This example decorates the ‘myFunction’ function with simple logger:
package main
import (
"log"
"fmt"
)
func decorator(fn func(s string)) func(s string) {
return func(s string) {
log.Println("starting")
fn(s)
log.Println("completed")
}
}
func myFunction(s string) {
fmt.Println(s)
}
func main() {
f := decorator(myFunction)
f("Hello Decorator")
// or decorator(myFunction)("Hello Decorator")
}
Applying decorators to the Standard Libraries’ HTTP Package
package main
import (
"fmt"
"log"
"net/http"
)
func simpleHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello World")
}
func decorator(f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Do extra stuff here, e.g. check API keys in header,
// restrict hosts etc
log.Println("Started", r.)
f(w, r) // call function here
log.Println("Done")
}
}
func main() {
http.HandleFunc("/decorated", decorator(simpleHandler))
http.HandleFunc("/notdecorated", simpleHandler)
http.ListenAndServe("127.0.0.1:8080", nil)
}
This way readable and simplicity are maintained by decorating the handlers in Go, which give the desired functionality without the dreaded code bloat.
ft_update_time2018-04-28 14:29