# README
go-middleware
[![Build Status][circleci-badge]][circleci-link]
Golang HTTP middleware
Installation
Since go-middleware
is an open source project and repository is public you can simply install it with go get
:
$ go get github.com/tiny-go/middleware
Currently available middleware
BodyClose
- closes request body for each requestContextDeadline
- sets request timeout (demands additional logic in your app)PanicRecover
- catches the panics inside our chain, can be used as error handler (similar totry/catch
) with corresponding panic handlerSetHeaders
- provides an easy way to set response headersJwtHS256
- verifies JWT (JSON Web Token) signed with HMAC signing method and parses its body to the provided receiver that is going to be available to next handlers through the request contextCodec
- searches for suitable request/response codecs according to "Content-Type"/"Accept" headers and puts them into the context
Experimental middleware
It means that work is still in progress, a lot of things can be changed or even completely removed
AsyncRequest
- allows to setrequest timeout
(for HTTP request) andasync timeout
(for background execution), if request has not been processed duringrequest timeout
- middleware returnsrequest ID
and HTTP code 202 (Accepted
). You can make a new request wtih givenrequest ID
later to obtain the result. The result can be provided only once and won't be available after that anymore. If handler did not finish its task duringasync timeout
- middleware sends an HTTP error with code 408 (RequestTimeout
) executing next async request with currentrequest ID
.
Examples
- Build the handler using middleware chaining functions:
-
New()
- start the chain. Can accept 0 (zero) or more arguments. -
Use()
- add middleware to existing chain. -
Then()
- set the final handler (which ishttp.Handler
).package main import ( "log" "net/http" "os" "github.com/tiny-go/middleware" "github.com/tiny-go/codec/driver" "github.com/tiny-go/codec/driver/json" "github.com/tiny-go/codec/driver/xml" ) var ( panicHandler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) { panic("something went wrong") } ) func main() { http.Handle( "/", middleware. // with HTTP panic handler New(middleware.PanicRecover(middleware.PanicHandler)). Use(middleware.BodyClose). Use(middleware.Codec(driver.DummyRegistry{&json.JSON{}, &xml.XML{}})). Then(panicHandler), ) log.Fatal(http.ListenAndServe(":8080", nil)) }
- Build the handler with
Chain()
(variadic) func which accepts the next list of argument types:
-
http.Handler
and everything else that implements this interface (for instance,http.HandlerFunc
) -
func(w http.ResponseWriter, r *http.Request)
-
MiddlewareFunc
/func(http.ResponseWriter, *http.Request, http.Handler)
-
Middleware
/func(http.Handler) http.Handler
There is no sense to provide entire example since import and variable declaration sections are going to be the same, only
main()
func is going to be changed:func main() { http.Handle( "/", middleware.Chain( // with custom panic handler middleware.PanicRecover(func(_ http.ResponseWriter, r interface{}) { if r != nil { log.Println(r) } }), middleware.BodyClose, panicHandler, ), ) log.Fatal(http.ListenAndServe(":8080", nil)) }