Skip to content

Instantly share code, notes, and snippets.

@whynotavailable
Last active March 9, 2020 22:31
Show Gist options
  • Save whynotavailable/d4443980a034b6a95b7dd99e55543673 to your computer and use it in GitHub Desktop.
Save whynotavailable/d4443980a034b6a95b7dd99e55543673 to your computer and use it in GitHub Desktop.
middleware example in go
package main
import (
"errors"
"log"
"net/http"
)
type handler func(writer http.ResponseWriter, request *http.Request, context map[string]string) error
type WebError struct {
StatusCode int
Message string
}
func (w WebError) Error() string {
return w.Message
}
func wrap(handlers ...handler) func(writer http.ResponseWriter, request *http.Request) {
return func(writer http.ResponseWriter, request *http.Request) {
context := make(map[string]string)
for _, handler := range handlers {
err := handler(writer, request, context)
if err != nil {
var webError WebError
if errors.As(err, &webError) {
// You could also marshal a JSON object here if your api deals with JSON.
writer.WriteHeader(webError.StatusCode)
_, _ = writer.Write([]byte(webError.Error()))
}
break
}
}
}
}
func tester(writer http.ResponseWriter, _ *http.Request, _ map[string]string) error {
_, _ = writer.Write([]byte("Yay!"))
return nil
}
func main() {
http.HandleFunc("/", wrap(authenticate, authorize("admin"), tester))
http.HandleFunc("/health", healthCheck) // no need for middleware here
log.Println("Starting")
_ = http.ListenAndServe(":8080", nil)
}
func healthCheck(writer http.ResponseWriter, _ *http.Request) {
_, _ = writer.Write([]byte("ok"))
}
func authorize(s string) handler {
return func(writer http.ResponseWriter, request *http.Request, context map[string]string) error {
if context["claim"] != s {
return WebError{
StatusCode: http.StatusUnauthorized,
Message: "No go bro",
}
}
return nil
}
}
func authenticate(_ http.ResponseWriter, request *http.Request, context map[string]string) error {
query := request.URL.Query()["claim"]
if len(query) > 0 {
context["claim"] = query[0]
return nil
} else {
return WebError{
StatusCode: http.StatusUnauthorized,
Message: "Missing claim bro",
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment