Git Product home page Git Product logo

httplayer's Introduction

httplayer

Disclaimer: this package is NOT another go HTTP router.

What is httplayer

Httplayer is a package designed to enhance the route building phase atop the standard Go HTTP router.

How is structured

You can access to the following functionalities:

  • Builder: A struct facilitating the construction of simple routes with middleware.
  • RoutingDefinition: A struct for building a collection of routes with shared middleware.
  • ServiceBuilder: A struct for assembling multiple services with distinct middlewares.
  • Mounting: Utilities functions to mount the built routes/services

Builder

The Builder struct offers a fluent api for constructing individual routes:

package main

import (
	"github.com/debyten/httplayer"
	"github.com/rs/cors"
	"net/http"
)

func main() {
	corsMw := cors.New(cors.Options{})
	myRoute := httplayer.NewBuilder(http.MethodGet, http.MethodPost).
		Path("/api/user").
		Middleware(corsMw).
		Handler(func(w http.ResponseWriter, r *http.Request) {
        // call stack is corsMw > handler
	}).
		Build()
	mux := http.NewServeMux()
	httplayer.MountRoute(mux, myRoute)
	http.ListenAndServe(":8080", mux)
}

RoutingDefinition

This includes more advanced middleware capabilities. You can define routes like so:

package main

import (
	"github.com/debyten/httplayer"
	"github.com/rs/cors"
	"net/http"
)

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

func main() {
	corsMw := cors.New(cors.Options{})
	def := httplayer.NewDefinition(corsMw).
		Add(http.MethodGet, "/api/user", userHandler)
	    // Add other routes ...
	mux := httplayer.Mount(def)
	http.ListenAndServe(":8080", mux)
}

ServiceBuilder

The ServiceBuilder is useful for combining multiple services with different middlewares:

package main

import (
	"github.com/debyten/httplayer"
	"github.com/rs/cors"
	"net/http"
)

func NewUserApi(svc UserService) httplayer.Routing {
	return userApi{svc: svc}
}

type userApi struct {
	svc UserService
}

func (u userApi) Routes(l *httplayer.RoutingDefinition) []httplayer.Route {
	return l.
		Add(http.MethodGet, "/api/users/{id}", u.findByIDApi).
		Add(http.MethodPost, "/api/users", u.createApi).
		Done()
}

func NewLoginApi(svc LoginService) httplayer.Routing {
	return loginApi{svc: svc}
}

type loginApi struct {
	svc LoginService
}

func (u loginApi) Routes(l *httplayer.RoutingDefinition) []httplayer.Route {
	return l.
		Add(http.MethodPost, "/api/login", u.loginApi, u.loginRateLimit).
		Done()
}

// Middleware
func (u loginApi) loginRateLimit(h http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
        // rate limit middleware impl
		h(w, r)
	}
}


func main() {
	corsMw := cors.New(cors.Options{})
	authMiddleware := ...
	userApi := NewUserApi(...)
	loginApi := NewLoginApi(...)
	protectedApis := httplayer.NewServiceBuilder(authMiddleware).Add(userApi)
	publicApis := httplayer.NewServiceBuilder().Add(loginApi)
	mux := httplayer.MountServices(protectedApis, publicApis)
	// we can add cors on top
	h := corsMw.Handler(mux)
	http.ListenAndServe(":8080", h)
}

Detach and Merge

These two functions allows to group features, for example, if we define an rbac middleware like so:

package main

func RBAC(roles ...string) func(http.HandlerFunc) http.HandlerFunc {
	return func(next http.HandlerFunc) http.HandlerFunc {
		return func(w http.ResponseWriter, r *http.Request) {
			// implementation
		}
	}
}

Then we can use the middleware while implementing the Service:

package main

type statsApi struct {
	svc StatsService
}

func (u statsApi) Routes(l *httplayer.RoutingDefinition) []httplayer.Route {
	adminRoutes := l.Detach(RBAC("admin")).
		Add(http.MethodPost, "/api/stats/purge", u.purgeApi)
	    Add(http.MethodPost, "/api/stats", u.pushStatApi)
	
	userRoutes := l.Detach(RBAC("user", "admin")).
		Add(http.MethodGet, "/api/stats", u.viewStatsApi).
	    Add(http.MethodPatch, "/api/stats/{id}", u.pinStatApi)
	return httplayer.Merge(adminRoutes, userRoutes)
}

In this way we share the middlewares from l (which is the main routing definition)

Mounting

To finalize the routing setup, you can employ the following functions to mount the routes onto a http.ServeMux:

  • MountRoute: This function installs the specified route onto the provided http.ServeMux.
  • Mount: Use this function to install a collection of RoutingDefinitions onto a new http.ServeMux.
  • DynamicMount: This function installs the given RoutingDefinition onto a new http.ServeMux and utilizes the input channel to dynamically register new Route instances in a separate goroutine.

For the last use case for example, you can think to an api gateway which automatically registers routes as new services are discovered.

httplayer's People

Contributors

almartino avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.