Middleware is often described as software glue. go-middleware focuses specifically on glueing together functions related to serving HTTP requests (such http.Handler/http.HandlerFunc).
Middleware is used for authentication (including Openid/OAuth redirects), authorization, request logging, error handling, request scoping, request throttling, request/response buffering, compression/decompression, CORS, CSRF, data binding, routing, content-type inference (rendering the result as JSON, XML as required), handling protocol upgrades (ex. Web Sockets), data hydration (ex. loading data into the request context based on an identifier (header/cookie) such as sessions), pre/post filters and more and are generally considered the 'core' of a web framework.
Having investigated multiple web frameworks on how they implement middleware; I found that none of them implemented middleware in what I consider idiomatic Go:
- Pluggability: Creating middleware or middleware-adapters shouldn't require a dependency on the middleware chaining implementation (ex. Go interfaces are satisfied implicitly) - See the context middleware
- Usability: Middleware can have multiple forms and shouldn't require satisfying a specific interface (ex. http.Handler/middleware.Middleware) to be used as such - See middleware.go type switch that supports 9 common variants
- Succinctness: The implementation should be concise and terse to reduce ambiguity and be considered self-documenting. middleware.go is 39 lines excluding white space and comments.
Go programming is different from traditional object oriented programming (OOP) and such existing implementations tend to translate poorly into Go.
import "net/http"
import "github.com/shelakel/go-middleware"
var handler http.HandlerFunc = middleware.Compose(...)
See example
go get -u github.com/shelakel/go-middleware
See GoDoc on Github
See LICENSE
done packages may be used
work in progress (WIP) packages should not be used - only for inspiration
TODO packages currently lack implementation
- context - based on context - done
- compression - WIP
- cors - WIP
- panic/recover error handling - WIP
- request logging - WIP
- static file server - TODO
- CSRF - nosurf - TODO
- Request throttling - TODO
- Request/Response buffering - TODO
- Auth - TODO
- Sessions - TODO
- bind - binding / schema - TODO
Middleware/Web Frameworks (for inspiration)
Links indicate interesting implementations
* can be converted or may be useful in middleware
- mango - context, sessions, error handling, static file server, basic auth
- martini - context, request logging, error handling, static file server, buferred response writer
- martini-contrib - "Accept-Language" header parsing, basic auth, binding, compression, render (view path provider), sessions, strip, web.go context adapter
- beego - context, error handling, cache*, validation*
- traffic - error handling, request logging, static file server
- handy - context
- handy handlers - https redirect, CORS, compression, request logging
- nosurf - CSRF middleware - can be used but not compatible for chaining as is
- revel - data binding, filters, flash cookies, validation* - See filter
- bones - context, sessions - See bones.web
- gorilla - context, mux, schema*, securecookie*, sessions, handlers*, websocket*, feeds* - See gorilla
Web Frameworks
- Shelakel
- Attribution for inspiration as per Middleware/Web Frameworks