lightweight, idiomatic and composable router for building Go HTTP services
lightweight, idiomatic and composable router for building Go HTTP services
[![GoDoc Widget]][GoDoc]
chi is a lightweight, idiomatic and composable router for building Go HTTP services. It's
especially good at helping you write large REST API services that are kept maintainable as your
project grows and changes. chi is built on the new context package introduced in Go 1.7 to
handle signaling, cancelation and request-scoped values across a handler chain.
The focus of the project has been to seek out an elegant and comfortable design for writing REST API servers, written during the development of the Pressly API service that powers our public API service, which in turn powers all of our client-side applications.
The key considerations of chi's design are: project structure, maintainability, standard http
handlers (stdlib-only), developer productivity, and deconstructing a large system into many small
parts. The core router github.com/go-chi/chi is quite small (less than 1000 LOC), but we've also
included some useful/optional subpackages: middleware, render
and docgen. We hope you enjoy it too!
go get -u github.com/go-chi/chi/v5
net/httpcontext package, providing value chaining, cancellations and timeoutsdocgen auto-generates routing documentation from your source to JSON or MarkdownSee _examples/ for a variety of examples.
As easy as:
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
func main() {
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("welcome"))
})
http.ListenAndServe(":3000", r)
}
REST Preview:
Here is a little preview of what routing looks like with chi. Also take a look at the generated routing docs in JSON (routes.json) and in Markdown (routes.md).
I highly recommend reading the source of the examples listed above, they will show you all the features of chi and serve as a good form of documentation.
…
chi's router is based on a kind of Patricia Radix trie.
The router is fully compatible with net/http.
Built on top of the tree is the Router interface:
…
Each routing method accepts a URL pattern and chain of handlers. The URL pattern
supports named params (ie. /users/{userID}) and wildcards (ie. /admin/*). URL parameters
can be fetched at runtime by calling chi.URLParam(r, "userID") for named parameters
and chi.URLParam(r, "*") for a wildcard parameter.
chi's middlewares are just stdlib net/http middleware handlers. There is nothing special about them, which means the router and all the tooling is designed to be compatible and friendly with any middleware in the community. This offers much better extensibility and reuse of packages and is at the heart of chi's purpose.
Here is an example of a standard net/http middleware where we assign a context key "user"
the value of "123". This middleware sets a hypothetical user identifier on the request
context and calls the next handler in the chain.
…
chi uses standard net/http request handlers. This little snippet is an example of a http.Handler func that reads a user identifier from the request context - hypothetically, identifying the user sending an authenticated request, validated+set by a previous middleware handler.
// HTTP handler accessing data from the request context.
func MyRequestHandler(w http.ResponseWriter, r *http.Request) {
// here we read from the request context and fetch out `"user"` key set in
// the MyMiddleware example above.
user := r.Context().Value("user").(string)
// respond to the client
w.Write([]byte(fmt.Sprintf("hi %s", user)))
}
chi's router parses and stores URL parameters right onto the request context. Here is an example of how to access URL params in your net/http handlers. And of course, middlewares are able to access the same information.
// HTTP handler accessing the url routing parameters.
func MyRequestHandler(w http.ResponseWriter, r *http.Request) {
// fetch the url parameter `"userID"` from the request of a matching
// routing pattern. An example routing pattern could be: /users/{userID}
userID := chi.URLParam(r, "userID")
// fetch `"key"` from the request context
ctx := r.Context()
key := ctx.Value("key").(string)
// respond to the client
w.Write([]byte(fmt.Sprintf("hi %v, %v", userID, key)))
}
chi comes equipped with an optional middleware package, providing a suite of standard
net/http middlewares. Please note, any middleware in the ecosystem that is also compatible
with net/http can be used with chi's mux.