Skip to content
Fast zero-allocation HTTP routing for Go ⚡️
Go
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.editorconfig
.gitignore
.travis.yml
CHANGELOG.md
LICENSE
README.md
chain.go
doc.go
example_test.go
go.mod
go.sum
params.go
router.go
router_test.go

README.md

mux (HTTP multiplexer for Go)

Build Status Sourcegraph GoDoc Minimal Version

About

This package is a fast HTTP multiplexer.

It uses a radix tree to match URLs. When matching simple routes, it's a zero allocation search. It's fast, simple and supports middlewares in an elegant way.

Usage

Full documentation [here].

Installing

Go 1.10

vgo get -u github.com/gbrlsnchs/mux

Go 1.11 or after

go get -u github.com/gbrlsnchs/mux

Importing

import (
	// ...

	"github.com/gbrlsnchs/mux"
)

Setting a handler (or handler function)

First, set a context key

type key uint8

const ctxKey key = 0

Then, create a new router and set an endpoint handler

rt := mux.NewRouter("/api", ctxKey)
rt.HandleFunc(http.MethodGet, "/ping", func(w http.ResponseWriter, _ *http.Request) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("pong"))
})

Setting a common middleware for every endpoint

First, define a middleware

func loggingFunc(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s %s", r.Method, r.URL.Path)
		next.ServeHTTP(w, r)
	})
}

Then, create a router and use the middleware in all requests

rt := mux.NewRouter("/api")
rt.Use(loggingFunc)
rt.Handle(http.MethodGet, "/ping", http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("pong"))
}))

Setting isolated middlewares

First, define a handler and some middlewares

func handler(w http.ResponseWriter, _ *http.Request) {
	w.WriteHeader(http.StatusOK)
})

func authFunc(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if mux.Params(r.Context(), ctxKey)["secret"] != "my_secret" {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func permissionFunc(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !userIsAdmin(r) { // hypothetical function
			w.WriteHeader(http.StatusForbidden)
			return
		}
		next.ServeHTTP(w, r)
	})
}

Then, create a middleware chain and add it to the router

rt := mux.NewRouter("/", ctxKey)
guard := mux.NewChain(authFunc, permissionFunc)

rt.Handle(http.MethodPost, "/unprotected", handler)
rt.Handle(http.MethodPost, "/protected/:secret", guard(handler))

Contributing

How to help

You can’t perform that action at this time.