Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

CoreyKaylor/gonion

Repository files navigation

Gonion

Build Status Coverage Status GoDoc

Gonion is a library for composing your routes and middleware. It is NOT a full-fledged framework, but rather allows you to compose things in a similar way that a framework might provide. Even though "idiomatic" go seems to encourage repeating yourself over and over again Gonion stays idiomatic without the repetition and loss of expressiveness.

Gonion has 0 reflection dependencies and adds 0 runtime alloc's to your routes and middleware.

Gonion is extremely fast!

Getting Started

Assuming you have installed gonion via go get github.com/CoreyKaylor/gonion

package main

import (
  "net/http"

  "github.com/CoreyKaylor/gonion"
	"github.com/julienschmidt/httprouter"
)

func main() {
	g := gonion.New()
	g.Get("/hello", http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
		rw.Write([]byte("Hello World!"))
	}))
	routes := g.BuildRoutes()
	router := httprouter.New() //use router of your choice
	for _, route := range routes {
		router.Handle(route.Method, route.Pattern, func(rw http.ResponseWriter, r *http.Request, m map[string]string) {
			route.Handler.ServeHTTP(rw, r)
		})
	}
	http.ListenAndServe(":3000", router)
}

Then go run server.go

You should now be able to open your browser to http://localhost:3000/

Middleware

Gonion handlers and middleware all take the form of the standard 'net/http' http.Handler

g.Use(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request){
	rw.Write([]byte("middleware"))
}))

When you need to wrap the downstream chain, rather than adding new signatures beyond the http.Handler gonion uses the middleware constructor method or in gonion terms the 'ChainLink'.

type ChainLink func(http.Handler) http.Handler

An example usage of a ChainLink

func wrappingHandler(inner http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
		//useless example, but this would be a good place to wrap the writer for something like gzip compression
		rw.Write([]byte("wrapping"))
		inner.ServeHTTP(rw, r)
	})
}

//and it's corresponding registration
g.Use().ChainLink(wrappingHandler)

Often it's useful to only apply middleware for 'POST' only routes. This removes the needless runtime checks for whether the current requests method is truly POST.

g.Only().Post().Use().ChainLink(wrappingHandler)

Typically middleware applies only to routes at a particular path.

g.Sub("/api", func(api *Composer){
	//middleware will only apply to routes with the prefix of /api
	api.Use().ChainLink(apiKeyHandler)
	api.Get("/users", http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request){
		rw.Write([]byte("Full route is /api/users"))
	}))
})

About

Simple golang route & middleware composer

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages