entre

package module
v0.0.0-...-b21e522 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2018 License: GPL-3.0 Imports: 10 Imported by: 1

README

entre

GoDoc

Another one of those Go Middleware libraries

The purpose of entre is to provide a lightweight middleware solution which works nicely both ways with httprouter as well as a range of other routers that simply use the core go http.Handler pattern.

There are other middleware libraries which are pretty great in terms of what you can throw their way with adapters for handlers implementing generic http.Handler interface.

For instance:

func myHandler(w http.ResponseWriter, r *http.Request) {
  // Do handling here
}

middleman.New(Middleware1, Middleware2, middleman.UseHandler(http.HandlerFunc(myHandler)))

Though none that I've come across work well with providing a the middleware object as a handler for a router which expects handlers of a different shape from the http.Handler interface.

For instance:

func myHandler(w http.ResponseWriter, r *http.Request, ctx mypkg.Context, params mypkg.Params) {
  // Do the handling here
}

mwHandler := middleman.New(Middleware1, Middleware2, middleman.UseMyRouterHandler(myHandler))
myRouter.Get("/entity/", mwHandler.AsMyRouterHandler())

That's where entre comes in to play.

Installing entre

go get github.com/freshwebio/entre

To use this package use:

import "github.com/freshwio/entre"

Handlers

You can use entre to provide middleware stacks for specific routes, route groups (where router provides route grouping) or to be used as the top level middleware for an application's core router.

You can use most handlers accepted by most go routers as a handler within an entre stack instance as with other middleware libraries.

Entre supports and provides an adapter for 2 main different types of handlers.

The first being the go core library http.Handler

router := httprouter.New()

func myHttpHandler(w http.ResponseWriter, r *http.Request) {
  // Do handling here
}

e := entre.New(Middleware1, Middleware2, entre.UseHandler(HandlerFunc(myHttpHandler)))
router.Handler("POST", "/entity/", e)

The second being the httprouter.Handle type which is simply a function which takes an extra parameter than that of the core http.Handler ServeHTTP function.

Entre provides built-in support to provide a middleware stack as a httprouter.Handle handler in order to retain and pass the httprouter.Params object through to the final handler in the chain.

router := httprouter.New()

func myHttpRouterHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
  // Do handling here
}

e := entre.New(Middleware1, Middleware2, entre.UseHTTPRouterHandler(myHttpRouterHandler))
router.POST("/entity/", e.ForHTTPRouter())

In the above providing the final handler using the UseHTTPRouterHandler wrapper method and the ForHTTPRouter method in providing the entre stack as a httprouter handler are both needed in order to pass the correct httprouter.Params object through the chain to the final handler.

Serving your app with entre

You can run your core web server from entre like the following:

router := httprouter.New()
e := entre.Bundled()
e.PushHandler(router)
e.Serve(":8383")

Or you could simply use entre as the main handler like the following:

router := httprouter.New()
e := entre.Bundled()
e.PushHandler(router)
http.ListenAndServe(":3000", e)

Bundled middleware

Entre comes with three built-in middleware items, you can set up an entre stack with the default middleware like so:

e := entre.Bundled(false, "user", "password")

The Bundled() method requires you provide three parameters:

  • Whether or not the panic recovery middleware should print the stack trace to the response.
  • The username for basic authentication.
  • The password for basic authentication.

You can also use the simpler utility method to create a new entre stack with just the logger and panic recovery middleware (defaults to print stack trace) without any parameters like so:

e := entre.Basic()
Logging

This middleware deals with logging incoming requests and their responses.

Example usage:

package main

import (
  "fmt"
  "net/http"

  "github.com/freshwebio/entre"
  "github.com/julienschmidt/httprouter"
)

func main() {
  router := httprouter.New()
  router.GET("/:entity", func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "This is entity %s", ps.ByName("entity"))
  })
  e := entre.New()
  e.Push(entre.NewLogger())
  e.PushHandler(router)
  e.Serve(":8283")
}

This will then print logs that will look something like the following:

|-entre-| Began GET /my-entity
|-entre-| Completed with 200 OK response in 234.653µs
Basic Authentication

This middleware deals with providing basic authentication through the use of the Authorization header.

Example usage:

package main

import (
  "fmt"
  "net/http"

  "github.com/freshwebio/entre"
  "github.com/julienschmidt/httprouter"
)

func main() {
  user := "user"
  password := "password"
  router := httprouter.New()
  router.GET("/:entity", func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "This is entity %s", ps.ByName("entity"))
  })
  e := entre.New()
  e.Push(entre.NewBasicAuth(user, password))
  e.PushHandler(router)
  e.Serve(":8283")
}
Panic recovery

This middleware deals with catching panics and produces a response with 500 status code. In the case other middleware may have written a response code or body that will take precedence over the response provided by the recovery middleware.

Example usage:

package main

import (
  "fmt"
  "net/http"

  "github.com/freshwebio/entre"
  "github.com/julienschmidt/httprouter"
)

func main() {
  router := httprouter.New()
  router.GET("/:entity", func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "This is entity %s", ps.ByName("entity"))
  })
  e := entre.New()
  // Provide true to print the stack trace of the panic to the response or false otherwise.
  e.Push(entre.NewPanicRecovery(true))
  e.PushHandler(router)
  e.Serve(":8283")
}

Further support

So far the implementation of entre will support most routers. Special adaptation was needed to integrate with the httprouter package both ways. If there is a router that takes a handler with a different shape from that of the standard http.Handler and you think entre should support it, create an issue on the repository.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BasicAuth

type BasicAuth struct {
	// contains filtered or unexported fields
}

BasicAuth provides the basic authentication middleware.

func NewBasicAuth

func NewBasicAuth(user string, password string) *BasicAuth

NewBasicAuth creates a new basic auth instance with the provided username and password.

func (*BasicAuth) ServeHTTP

func (b *BasicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request, ps httprouter.Params, next http.HandlerFunc)

type Entre

type Entre struct {
	// contains filtered or unexported fields
}

Entre provides the functionality for the entre middleware handler.

func Basic

func Basic() *Entre

Basic create a new entre middleware stack from the bundled middleware taking no parameters. This produces a stack with a logging middleware and a panic recovery middleware which prints the panic stack trace to the response.

func Bundled

func Bundled(printStack bool, user string, pass string) *Entre

Bundled creates a new entre middleware stack from the bundled middleware.

func New

func New(mw ...Handler) *Entre

New deals with creating a new Entre with the provided middleware.

func (*Entre) ForHTTPRouter

func (e *Entre) ForHTTPRouter() httprouter.Handle

ForHTTPRouter provides an Entre object as a httprouter handler for application's using the httprouter for routing.

func (*Entre) Push

func (e *Entre) Push(h Handler)

Push takes a handler and adds it to the handler list.

func (*Entre) PushFunc

PushFunc adds a handler function of the entre handler type to the stack of middleware.

func (*Entre) PushHandler

func (e *Entre) PushHandler(h http.Handler)

PushHandler adds a http.Handler to the stack of middleware.

func (*Entre) PushHandlerFunc

func (e *Entre) PushHandlerFunc(hf func(http.ResponseWriter, *http.Request))

PushHandlerFunc adds a http.HandlerFunc based handler on to our stack of middleware.

func (*Entre) Serve

func (e *Entre) Serve(addr string)

Serve deals with setting up with the web server to listen to the provided port.

func (*Entre) ServeHTTP

func (e *Entre) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP deals with invoking the entre middleware chain for the standard http.Handler integration.

func (*Entre) ServeHTTPForHTTPRouter

func (e *Entre) ServeHTTPForHTTPRouter(w http.ResponseWriter, r *http.Request, ps httprouter.Params)

ServeHTTPForHTTPRouter is the endpoint handler for integration with the httprouter router.

type Handler

type Handler interface {
	ServeHTTP(w http.ResponseWriter, r *http.Request, params httprouter.Params, next http.HandlerFunc)
}

Handler provides the base definition for an entre handler that provides the core middleware functionality.

func UseHTTPRouterHandler

func UseHTTPRouterHandler(h httprouter.Handle) Handler

UseHTTPRouterHandler wraps a httprouter handler so it can be used as the part of then entre middleware chain.

func UseHandler

func UseHandler(h http.Handler) Handler

UseHandler provides a way to wrap a http.Handler in an entre.Handler to be used as middleware.

func UseNextHandler

func UseNextHandler(h NextHandler) Handler

UseNextHandler allows entre to take handlers with a next argument.

func UseNextHandlerFunc

func UseNextHandlerFunc(h NextHandlerFunc) Handler

UseNextHandlerFunc allows us to use a handler which allows calling of the next handler in the chain without the expectation of router params.

type HandlerFunc

HandlerFunc provides the definition for a handler function.

func (HandlerFunc) ServeHTTP

type Logger

type Logger struct {
	LoggerIface
}

Logger is the type which provides our core logging middleware.

func NewLogger

func NewLogger() *Logger

NewLogger creates a new logger middleware instance.

func (*Logger) ServeHTTP

func (l *Logger) ServeHTTP(w http.ResponseWriter, r *http.Request, ps httprouter.Params, next http.HandlerFunc)

type LoggerIface

type LoggerIface interface {
	Println(...interface{})
	Printf(string, ...interface{})
}

LoggerIface provides a minimal interface with our middleware logger with the funcionality of a simple middleware logger.

type NextHandler

type NextHandler interface {
	ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}

NextHandler provides the definition for a handler that is not coupled with the httprouter package but allows us to make use of middleware primarily written for libraries like negroni.

type NextHandlerFunc

type NextHandlerFunc func(http.ResponseWriter, *http.Request, http.HandlerFunc)

NextHandlerFunc provides the definition for a handler function which does not make use of httprouter.Params, this is for middleware components built for other routers that have include a reference to the next handler in the chain.

func (NextHandlerFunc) ServeHTTP

func (h NextHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)

type PanicRecovery

type PanicRecovery struct {
	Logger           LoggerIface
	PrintStack       bool
	ErrorHandlerFunc func(interface{})
	StackAll         bool
	StackSize        int
}

PanicRecovery is the middleware that handles recovery from panics.

func NewPanicRecovery

func NewPanicRecovery(printStack bool) *PanicRecovery

NewPanicRecovery deals with create a new instance to be used in a middleware stack.

func (*PanicRecovery) ServeHTTP

type Response

type Response interface {
	http.ResponseWriter
	http.Flusher
	// Status returns the code of the response or 200 if the status code
	// has not yet been written to the response.
	Status() int
	// Written determines whether or not response has been written to.
	Written() bool
	// BodyLength retrieves the size of the response body.
	BodyLength() int
	// Before provides a way for functions to be called before a response is written.
	// This comes in to play for tasks like setting headers.
	Before(func(Response))
}

Response provides a wrapper around http.ResponseWriter to make it easier for middleware to evaluate and retrieve information from responses.

func NewResponse

func NewResponse(w http.ResponseWriter) Response

NewResponse provides a wrapper response instance for the provided resposne writer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL