⚡️ A lightning fast HTTP router

gowww router GoDoc Build Coverage Go Report Status Stable

Package router provides a lightning fast HTTP router.

Features

  • Extreme performance: sub-microsecond routing in most cases
  • Full compatibility with the http.Handler interface
  • Generic: no magic methods, bring your own handlers
  • Path parameters, regular expressions and wildcards
  • Smart prioritized routes
  • Zero memory allocations during serving (but for parameters)
  • Respecting the principle of least surprise
  • Tested and used in production

Installing

  1. Get package:

    go get -u github.com/gowww/router
  2. Import it in your code:

    import "github.com/gowww/router"

Usage

  1. Make a new router:

    rt := router.New()
  2. Make a route:

    rt.Handle("GET", "/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    	fmt.Fprint(w, "Hello")
    }))

    Remember that HTTP methods are case-sensitive and uppercase by convention (RFC 7231 4.1).
    So you can directly use the built-in shortcuts for standard HTTP methods: Router.Get, Router.Post, Router.Put, Router.Patch and Router.Delete.

  3. Give the router to the server:

    http.ListenAndServe(":8080", rt)

Parameters

Named

A named parameter begins with : and matches any value until the next / or end of path.

To retrieve the value (stored in request's context), ask Parameter.
It will return the value as a string.

Example, with a parameter id:

rt.Get("/users/:id", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	id := router.Parameter(r, "id")
	fmt.Fprintf(w, "Page of user #%s", id)
}))
No surprise

A parameter can be used on the same level as a static route, without conflict:

rt.Get("/users/all", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "All users page")
}))

rt.Get("/users/:id", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	id := router.Parameter(r, "id")
	fmt.Fprintf(w, "Page of user #%s", id)
}))

Regular expressions

If a parameter must match an exact pattern (digits only, for example), you can also set a regular expression constraint just after the parameter name and another ::

rt.Get(`/users/:id:^\d+$`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	id := router.Parameter(r, "id")
	fmt.Fprintf(w, "Page of user #%s", id)
}))

If you don't need to retrieve the parameter value but only use a regular expression, you can omit the parameter name:

rt.Get(`/shows/::^prison-break-s06-.+`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Prison Break S06 — Coming soon…")
}))

Don't forget that regular expressions can significantly reduce performance.

No surprise

A parameter with a regular expression can be used on the same level as a simple parameter, without conflict:

rt.Get(`/users/:id:^\d+$`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	id := router.Parameter(r, "id")
	fmt.Fprintf(w, "Page of user #%s", id)
}))

rt.Get("/users/:name", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	name := router.Parameter(r, "name")
	fmt.Fprintf(w, "Page of %s", name)
}))

Wildcard

A trailing slash in a route path is significant.
It behaves like a wildcard by matching the beginning of the request path.
The rest of the request path becomes the parameter value of *:

rt.Get("/files/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	filepath := router.Parameter(r, "*")
	fmt.Fprintf(w, "Get file %s", filepath)
}))

Note that a trailing slash in a request path is always trimmed and the client redirected.
For example, a request for /files/ will be redirected to /files and will never match a /files/ route.
In other words, /files and /files/ are two different routes.

No surprise

Deeper route paths with the same prefix as the wildcard will take precedence, without conflict:

// Will match:
// 	/files/one
// 	/files/two
// 	...
rt.Get("/files/:name", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {kv
	name := router.Parameter(r, "name")
	fmt.Fprintf(w, "Get root file #%s", name)
}))

// Will match:
// 	/files/one/...
// 	/files/two/...
// 	...
rt.Get("/files/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	filepath := router.Parameter(r, "*")
	fmt.Fprintf(w, "Get file %s", filepath)
}))

// Will match:
// 	/files/movies/one
// 	/files/movies/two
// 	...
rt.Get("/files/movies/:name", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	name := router.Parameter(r, "name")
	fmt.Fprintf(w, "Get movie #%s", name)
}))

Static files

For serving static files, like for other routes, just bring your own handler.

Example, with the standard net/http.FileServer:

rt.Get("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

Custom "not found" handler

When a request match no route, the response status is set to 404 and an empty body is sent by default.

But you can set your own "not found" handler.
In this case, it's up to you to set the response status code (normally 404):

rt.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	http.NotFound(w, r)
})
Owner
HTTP handlers and utilities
null
Similar Resources

High-speed, flexible tree-based HTTP router for Go.

httptreemux High-speed, flexible, tree-based HTTP router for Go. This is inspired by Julien Schmidt's httprouter, in that it uses a patricia tree, but

Dec 28, 2022

A powerful HTTP router and URL matcher for building Go web servers with 🦍

gorilla/mux https://www.gorillatoolkit.org/pkg/mux Package gorilla/mux implements a request router and dispatcher for matching incoming requests to th

Jan 9, 2023

Go HTTP router

violetear Go HTTP router http://violetear.org Design Goals Keep it simple and small, avoiding extra complexity at all cost. KISS Support for static an

Dec 10, 2022

lightweight, idiomatic and composable router for building Go HTTP services

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

Jan 8, 2023

:tongue: CleverGo is a lightweight, feature rich and high performance HTTP router for Go.

CleverGo CleverGo is a lightweight, feature rich and trie based high performance HTTP request router. go get -u clevergo.tech/clevergo English 简体中文 Fe

Nov 17, 2022

Simple router build on `net/http` supports custom middleWare.

XMUS-ROUTER Fast lightweight router build on net/http supports delegate and in url params. usage : Create new router using NewRouter() which need rout

Dec 27, 2021

Simple HTTP router for Go

ngamux Simple HTTP router for Go Installation Examples Todo Installation Run this command with correctly configured Go toolchain. go get github.com/ng

Dec 13, 2022

Lightweight Router for Golang using net/http standard library with custom route parsing, handler and context.

Go-Lightweight-Router Lightweight Router for Golang using net/http standard library with custom route parsing, handler and context. Further developmen

Nov 3, 2021

A high performance HTTP request router that scales well

HttpRouter HttpRouter is a lightweight high performance HTTP request router (also called multiplexer or just mux for short) for Go. In contrast to the

Dec 9, 2021
Comments
  • very simple static routing for

    very simple static routing for "/" doesn't seam to work

    The following code doesn't return some files in my ./www directory. My ./www directory contains two files ./www/index.html and ./www/css/main.css. Note that the css file is in a subdirectory named css.

    When performing a get on http://localhost:8080 I get back the index.html file, but the css file is not returned.

    Here is the code:

    func main() {
    	rt := router.New()
    	rt.Get("/", http.FileServer(http.Dir("www")))
    	http.ListenAndServe(":8080", rt)
    }
    

    When using the default server mux, I have no problem. I get the css file and the style is right.

    func main() {
    	http.Handle("/", http.FileServer(http.Dir("www")))
    	http.ListenAndServe(":8080", nil)
    }
    
  • Sorting by number of childrens is not usefull

    Sorting by number of childrens is not usefull

    I implemented a simple radix tree and did some tests. Based on my benchmarking tests, this algorithm is so fast that sorting doesn't make any significant difference. I would suggest you reconsider sorting by number of children.

    What might show a difference is to put expensive tests last. So static path segments first, parameters without regex next and parameters with regex last. Sorting in this order needs only to update the modified children array.

    I like to take the opportunity to congratulate you for the remarkable performance of your routing package. The no surprise is perfect too. Thank you.

  • Question: adding a Handle with no Handler function ?

    Question: adding a Handle with no Handler function ?

    Looking at the code I don't understand the logic regarding nil handler in makeChild. Why would a user call router.Handle with a nil handle ? When can this happen ?

FastRouter is a fast, flexible HTTP router written in Go.

FastRouter FastRouter is a fast, flexible HTTP router written in Go. FastRouter contains some customizable options, such as TrailingSlashesPolicy, Pan

Sep 27, 2022
:rotating_light: Is a lightweight, fast and extensible zero allocation HTTP router for Go used to create customizable frameworks.
:rotating_light: Is a lightweight, fast and extensible zero allocation HTTP router for Go used to create customizable frameworks.

LARS LARS is a fast radix-tree based, zero allocation, HTTP router for Go. view examples. If looking for a more pure Go solution, be sure to check out

Dec 27, 2022
An extremely fast Go (golang) HTTP router that supports regular expression route matching. Comes with full support for building RESTful APIs.

ozzo-routing You may consider using go-rest-api to jumpstart your new RESTful applications with ozzo-routing. Description ozzo-routing is a Go package

Dec 31, 2022
Pure is a fast radix-tree based HTTP router
Pure is a fast radix-tree based HTTP router

package pure Pure is a fast radix-tree based HTTP router that sticks to the native implementations of Go's "net/http" package; in essence, keeping the

Dec 1, 2022
xujiajun/gorouter is a simple and fast HTTP router for Go. It is easy to build RESTful APIs and your web framework.

gorouter xujiajun/gorouter is a simple and fast HTTP router for Go. It is easy to build RESTful APIs and your web framework. Motivation I wanted a sim

Dec 8, 2022
Fast and flexible HTTP router
Fast and flexible HTTP router

treemux - fast and flexible HTTP router Basic example Debug logging CORS example Error handling Rate limiting using Redis Gzip compression OpenTelemet

Dec 27, 2022
Fast, simple, and lightweight HTTP router for Golang

Sariaf Fast, simple and lightweight HTTP router for golang Install go get -u github.com/majidsajadi/sariaf Features Lightweight compatible with net/ht

Aug 19, 2022
Simple Golang HTTP router
Simple Golang HTTP router

Bellt Simple Golang HTTP router Bellt Package implements a request router with the aim of managing controller actions based on fixed and parameterized

Sep 27, 2022
Go Server/API micro framework, HTTP request router, multiplexer, mux
Go Server/API micro framework, HTTP request router, multiplexer, mux

?? gorouter Go Server/API micro framework, HTTP request router, multiplexer, mux. ?? ABOUT Contributors: Rafał Lorenz Want to contribute ? Feel free t

Dec 16, 2022
A high performance HTTP request router that scales well

HttpRouter HttpRouter is a lightweight high performance HTTP request router (also called multiplexer or just mux for short) for Go. In contrast to the

Dec 28, 2022