hitch: middleware + routing for vanilla go http.Handlers — https://github.com/nbio/hitch

November 29, 2014 · View on GitHub

package main

import ( "fmt" "net/http"

"github.com/nbio/hitch"
"github.com/nbio/httpcontext"
"github.com/nbio/httpgzip"

)

func main() { h := hitch.New() h.Use(Logger, httpgzip.GzipResponse, SetUser) h.Get("/", http.HandlerFunc(Home))

items := hitch.New()
items.Use(NestedMiddleware)
items.Get("/items", http.HandlerFunc(Items))
items.Get("/items/:id", http.HandlerFunc(Item))
h.Next(items)

http.ListenAndServe(":8000", h)

}

func Logger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { fmt.Printf("%s %s\n", req.Method, req.URL.String()) next.ServeHTTP(w, req) }) }

type key int

const userKey key = 0

// SetUser middleware sets the User member of a RequestContext for // subsequent handlers to depend on. func SetUser(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.ParseForm() user := req.Form.Get("user") w.Header().Set("X-User", user) httpcontext.Set(req, userKey, user) next.ServeHTTP(w, req) }) }

func Home(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") fmt.Fprintf(w, "Welcome home, %s!\n", httpcontext.GetString(req, userKey)) }

func NestedMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.Header().Set("X-Nested-Middleware", "active") next.ServeHTTP(w, req) }) }

func Items(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") fmt.Fprintf(w, "Showing all items\n") }

func Item(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") fmt.Fprintf(w, "Showing item: %s\n", hitch.Params(req).ByName("id")) }