Last active
April 26, 2023 00:41
-
-
Save paxan/5b8ecb8e51f633c712d161f911b6e211 to your computer and use it in GitHub Desktop.
HTTP middlewares in Go from the first principles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"log" | |
"net/http" | |
"sync/atomic" | |
) | |
// hello is your HTTP web application. | |
func hello() http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
fmt.Fprintf(w, "hello world (rid: %q)\n", RID(r.Context())) | |
}) | |
} | |
// addRID is a middleware that grabs the request ID value from the specified | |
// header, and puts into the request context passed to the upstream handler. | |
func addRID(ridHeader string, handler http.Handler) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
handler.ServeHTTP( | |
w, | |
r.WithContext(context.WithValue( | |
r.Context(), | |
ridKey, | |
r.Header.Get(ridHeader)))) | |
}) | |
} | |
// RID returns the request ID from the context. | |
func RID(ctx context.Context) string { | |
rid, _ := ctx.Value(ridKey).(string) | |
return rid | |
} | |
var ridKey = &struct{ name string }{"request id"} | |
// requestCounter is a middleware that counts requests. | |
func requestCounter(handler http.Handler) http.Handler { | |
var count uint64 | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
log.Printf("request count: %v", atomic.AddUint64(&count, 1)) | |
handler.ServeHTTP(w, r) | |
}) | |
} | |
func main() { | |
http.ListenAndServe( | |
"localhost:8888", | |
requestCounter( | |
addRID("X-RID", | |
hello()))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment