Last active
August 29, 2015 14:09
-
-
Save omeid/8246f4094bca78a69bb0 to your computer and use it in GitHub Desktop.
Node.js (Express) Style Go Middleware in 40 line of code.
This file contains 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 ( | |
"log" | |
"net/http" | |
"time" | |
) | |
type Handler func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) | |
type stack struct { | |
handler Handler | |
next *stack | |
} | |
var noop = &stack{func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {}, &stack{}} | |
func (s stack) ServeHTTP(rw http.ResponseWriter, r *http.Request) { | |
s.handler(rw, r, s.next.ServeHTTP) | |
} | |
func App(handle Handler) *stack { | |
return &stack{handle, noop} | |
} | |
func (s *stack) Use(handler Handler) *stack { | |
if s.next != noop { | |
return s.next.Use(handler) | |
} | |
s.next = &stack{handler, noop} | |
return s | |
} | |
func (s *stack) Run(addr string) { | |
log.Printf("Listening on: %s\n\n", addr) | |
log.Fatal(http.ListenAndServe(addr, s)) | |
} | |
//Example Usage: | |
func logger(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { | |
start := time.Now() | |
log.Printf("Started %s %s", r.Method, r.URL.Path) | |
next(rw, r) | |
log.Printf("Completed %s %s in %v\n\n", r.Method, r.URL.Path, time.Since(start)) | |
} | |
// Wrapper for http.Handlers | |
func Wrap(h http.Handler) Handler { | |
return func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { | |
h.ServeHTTP(rw, r) | |
next(rw, r) | |
} | |
} | |
func main() { | |
fs := http.FileServer(http.Dir("/usr/share/doc")) | |
app := App(logger) | |
app.Use(Wrap(fs)) | |
//Oh, and print the useragent IP. | |
app.Use(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { | |
log.Printf("Useragent IP %s", r.RemoteAddr) | |
next(rw, r) | |
}) | |
//Now lets run it! | |
app.Run(":8080") | |
//as 'stack' is a http.Handler, so you can use it like this too. | |
//log.Fatal(http.ListenAndServe(":8080", app)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment