One of the things I really like about Go is the way it encourages you to build up behaviour using composition. For example, I was writing handlers that return a response object as json; it’s very simple to extract the duplicated code into a generic handler:
package main
import (
"encoding/json"
"log"
"net/http"
)
type ResponseGenerator interface {
GetResponse(r *http.Request) (interface{}, error)
}
type JsonHandler struct {
log *log.Logger
rg ResponseGenerator
}
func (h *JsonHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
response, err := h.rg.GetResponse(r)
if err != nil {
h.log.Printf("ERROR: %v\n", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
b, err := json.Marshal(response)
if err != nil {
h.log.Printf("ERROR: %v\n", err)
http.Error(w, "Unexpected error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(b)
}