Popularity
3.3
Declining
Activity
0.0
Stable
54
6
7

Programming language: Go
License: MIT License
Tags: Web Frameworks     Routers    

bellt alternatives and similar packages

Based on the "Routers" category.
Alternatively, view bellt alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of bellt or a related project?

Add another 'Routers' Package

README

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.


*Note that all licence references and agreements mentioned in the bellt README section above are relevant to that project's source code only.