Simple Golang HTTP router

Bellt

Simple Golang HTTP router

Mentioned in Awesome Go License: MIT Go Report Card codecov Build Status GitHub GoDoc

Bellt Package implements a request router with the aim of managing controller actions based on fixed and parameterized routes.

The project so far has the following functionalities:

  • Standard definition of route "/ health", in order to prepare the service developed with bellt to act as microservice.
  • Providing the creation of parameterized routes, simple or segmented (groups).
  • All requests can be made through fixed patterns, querystrings and parameters.
  • Obtaining the requisition parameters in the controller functions.

Summary

Install

To get Bellt

> Go CLI
go get -u github.com/GuilhermeCaruso/bellt
> Go DEP
dep ensure -add github.com/GuilhermeCaruso/bellt
> Govendor
govendor fetch github.com/GuilhermeCaruso/bellt

Guide

Router

To initialize our router

var router = bellt.NewRouter()
package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/GuilhermeCaruso/bellt"
)

func main() {
	router := bellt.NewRouter()

	log.Fatal(http.ListenAndServe(":8080", nil))
}

HandleFunc

HandleFunc function responsible for initializing a common route or built through the Router. All non-grouped routes must be initialized by this method.

/*
	[path] - Endpoint string
	[handlerFunc] - Function that will be called on the request
	[methods] - Slice for endpoint methods ("GET", "POST", "PUT", "DELETE")
*/

router.HandleFunc(path, handlerFunc, methods)
    
package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/GuilhermeCaruso/bellt"
)

func main() {
	router := bellt.NewRouter()

	router.HandleFunc("/bellt", belltHandler, "GET")

	log.Fatal(http.ListenAndServe(":8080", nil))
}

func belltHandle(w http.ResponseWriter, r *http.Request){
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Simple Golang HTTP router")
}

HandleGroup

HandleGroup is responsible for creating a group of routes. The main path can be set for all other routes.

/*
	[mainPath] - Main route used in all subr-outes
	
	[subHandleFunc] - SubHandleFunc function responsiblefor initializing a common route or
	built through the Router. All grouped routes must be initialized by this method
*/

router.HandleGroup(mainPath, ...SubHandleFunc)
    

SubHandleFunc

SubHandleFunc is responsible for initializing a common or built route. Its use must be made within the scope of the HandleGroup method, where the main path will be declared.

/*
	[path] - Endpoint string
	[handlerFunc] - Function that will be called on the request
	[methods] - Slice for endpoint methods ("GET", "POST", "PUT", "DELETE")
*/

router.SubHandleFunc(path, handlerFunc, methods)
    
package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/GuilhermeCaruso/bellt"
)

func main() {
	router := bellt.NewRouter()

	router.HandleGroup("/api",
		router.SubHandleFunc("/bellt", belltHandle, "GET"),
		router.SubHandleFunc("/check", checkHandle, "GET"),
	)

	log.Fatal(http.ListenAndServe(":8080", nil))
}

func belltHandle(w http.ResponseWriter, r *http.Request){
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Simple Golang HTTP router")
}

func checkHandle(w http.ResponseWriter, r *http.Request){
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Ok!")
}

Middleware

The declaration of middlewares in HandleFunc or SubHandleFunc should be done using the Use method

Use

/*
	handlerFunc - Function that will be called on the request 
	middlewareList - Slice of middleware that will be used in the request (Middleware)
*/
bellt.Use(handlerFunc, ...middlewareList)

The middleware type has a following signature

type Middleware func(http.HandlerFunc) http.HandlerFunc

Applying middlewares to routes

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/GuilhermeCaruso/bellt"
)

func main() {

	router := bellt.NewRouter()

	router.HandleFunc("/hello", bellt.Use(
		exampleHandler,
		middlewareOne,
		middlewareTwo,
	), "GET")

	router.HandleGroup("/api",
		router.SubHandleFunc("/hello", bellt.Use(
			exampleHandler,
			middlewareOne,
			middlewareTwo,
		), "GET"),
	)

	log.Fatal(http.ListenAndServe(":8080", nil))
}

func exampleHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(`Hello Middleware!`))
}

func middlewareOne(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("Step One")
		next.ServeHTTP(w, r)
	}
}

func middlewareTwo(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("Step Two")
		next.ServeHTTP(w, r)
	}
}

Parameterized Routes

Route parameters must be passed using {} as scope limiter

router.HandleFunc("/hello/{name}", handlerFunc, "GET")

router.HandleGroup("/api", 
	SubHandleFunc("/item/{id}", handlerFunc, "GET")
)

Route Variables

RouteVariables used to capture and store parameters passed to built routes.

Need to pass the *Request of the HandlerFunc used in the HandleFunc method.

/*
	r = *Request of the HandlerFunc
*/
rv := bellt.RouteVariables(r)

The declaration must be made within the HandlerFunc

func exampleHandler(w http.ResponseWriter, r *http.Request) {
	rv := bellt.RouteVariables(r)
	/*[...]*/
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Hello!"))
}

GetVar

GetVar returns the parameter value of the route

/*
	r = *Request of the HandlerFunc
	param = Parameter name string
*/
rv := bellt.RouteVariables(r)

rv.GetVar(param)
func exampleHandler(w http.ResponseWriter, r *http.Request) {
	rv := bellt.RouteVariables(r)
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(fmt.Sprintf(`Hello %v gopher!`, rv.GetVar("color")))))
}

The complete implementation of parameterized routes should look like this:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/GuilhermeCaruso/bellt"
)

func main() {

	router := bellt.NewRouter()

	router.HandleFunc("/contact/{id}/{user}", exampleHandler, "GET")

	router.HandleGroup("/api",
		router.SubHandleFunc("/check/{id}/{user}", exampleHandler, "GET"),
	)

	log.Fatal(http.ListenAndServe(":8080", nil))
}

func exampleHandler(w http.ResponseWriter, r *http.Request) {
	rv := bellt.RouteVariables(r)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(fmt.Sprintf(`{"id": %v, "user": %v}`, rv.GetVar("user"), rv.GetVar("id"))))
}

Full Example

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/GuilhermeCaruso/bellt"
)

func main() {

	router := bellt.NewRouter()

	router.HandleFunc("/contact/{id}/{user}", bellt.Use(
		exampleHandler,
		middlewareOne,
		middlewareTwo,
	), "GET")

	router.HandleFunc("/contact", bellt.Use(
		exampleNewHandler,
		middlewareOne,
		middlewareTwo,
	), "GET")

	router.HandleGroup("/api",
		router.SubHandleFunc("/check", bellt.Use(
			exampleNewHandler,
			middlewareOne,
			middlewareTwo,
		), "GET"),
		router.SubHandleFunc("/check/{id}/{user}", bellt.Use(
			exampleHandler,
			middlewareOne,
			middlewareTwo,
		), "GET"),
	)

	log.Fatal(http.ListenAndServe(":8080", nil))
}

func exampleHandler(w http.ResponseWriter, r *http.Request) {

	rv := bellt.RouteVariables(r)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(fmt.Sprintf(`{"id": %v, "user": %v}`, rv.GetVar("user"), rv.GetVar("id"))))
}

func exampleNewHandler(w http.ResponseWriter, r *http.Request) {
	rv := bellt.RouteVariables(r)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(`{"msg": "Works"}`))
}

func middlewareOne(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("Step One")

		next.ServeHTTP(w, r)
	}
}

func middlewareTwo(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("Step Two")

		next.ServeHTTP(w, r)
	}
}

Benchmark

Applying requisition performance tests, the following results were obtained, showing the initial potency of the Bellt package.

Author

Guilherme Caruso @guicaruso_ on twitter

Presentation

Guilherme Caruso - Cabify- GolangSP Meetup 2 - 21/03/2019 - São Paulo /Brazil

Slides - Construindo Rotas Parametrizadas em GO

Video - GolangSP Meetup 2

License

MIT licensed. See the LICENSE file for details.

Owner
Guilherme Caruso
Software Engineer | Go Evangelist | Beginner Rustacean | INTP-T |
Guilherme Caruso
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

: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

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

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

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

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

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
  • Fix test case that was comparing the same operands.

    Fix test case that was comparing the same operands.

    Hey there! I was scanning a bunch of Go code and found this issue. It looks like this test case in bellt/pkg/command_test.go intended to compare want to command but was comparing command twice. This PR fixes that. Hope it's helpful!

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
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
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
Simple http router.

Simple router based on tree structure. import ( "fmt" "log" "net/http" router "github.com/dmitruk-v/router/v1" ) func main() { ro := router.New

Dec 29, 2021
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
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
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
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