When I read article https://upgear.io/blog/golang-tip-wrapping-http-response-writer-for-middleware/?utm_source=golangweekly&utm_medium=email, I realize that is easy to make a wrapper (design pattern Proxy), that wrap some methods.
Situation is bit complicated, when you don't want loose an interface, when wrapped object had it.
In example example I've written how to optionally implement http.Flusher. But how to solve a situation from article, when w could implement some of 3 interfaces (http.Flusher, http.Hijacker, http.Pusher). Is it better solution, that write 8 different types, where each implements combination of previous?
// add type, that do what statusRecorder, but keeps ability to be Flusher
type statusRecordFlusher statusRecorder
func (w *statusRecordFlusher) Flush() {
w.ResponseWriter.(http.Flusher).Flush()
}
// and decision, how to wrap
func logware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Initialize the status to 200 in case WriteHeader is not called
var rec http.ResponseWriter
if _, ok := w.(http.Flusher); ok {
rec = &statusRecordFlusher{w, 200}
} else {
rec = &statusRecorder{w, 200}
}
next.ServeHTTP(rec, r)
})
}
You're embedding
ResponseWriter, and shadowingFlushwithout adding any behavior; remove the shadow method. You'll still need to do some type wrangling, but you don't need to do any method implementations unless you're trying to add or alter behavior (presumably justWriteHeaderbased on the question).Because you're just trying to expose methods of embedded types here, you don't even need to define all the structs, you can use anonymous structs (playground example here):