alice

repository·master·Indexed 25 days ago

https://github.com/justinas/alice

A minimal middleware chaining library for Go that simplifies the nesting of HTTP middleware functions. It provides a fluent interface to chain multiple middleware constructors of the signature `func(http.Handler) http.Handler` using `alice.New()` and apply them to a handler via `Then()` or `ThenFunc()`.

Tokens
1K
Snippets
3
Records
9
Agent score
36%

What's inside alice

  1. Chain HTTP middleware with Alice

    master

    Alice provides a way to chain multiple HTTP middleware functions and an application handler using a fluent interface. Instead of manually nesting middleware calls like Middleware1(Middleware2(App)), you can use alice.New() to create a chain and .Then() to attach your final handler.

    To use Alice, your middleware constructors must follow the signature: func(http.Handler) http.Handler.

    If a middleware does not follow this signature, you can wrap it in a compatible function.

  2. Full usage example of Alice middleware chaining

    master

    This example demonstrates how to combine multiple middleware (throttling, timeout handling, and CSRF protection) into a single chain using alice.New().Then().

    package main
    
    import (
        "net/http"
        "time"
    
        "github.com/throttled/throttled"
        "github.com/justinas/alice"
        "github.com/justinas/nosurf"
    )
    
    func timeoutHandler(h http.Handler) http.Handler {
        return http.TimeoutHandler(h, 1*time.Second, "timed out")
    }
    
    func myApp(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello world!"))
    }
    
    func main() {
        th := throttled.Interval(throttled.PerSec(10), 1, &throttled.VaryBy{Path: true}, 50)
        myHandler := http.HandlerFunc(myApp)
    
        chain := alice.New(th.Throttle, timeoutHandler, nosurf.NewPure).Then(myHandler)
        http.ListenAndServe(":8000", chain)
    }
  3. Implement compatible middleware for Alice

    master

    Alice requires middleware to be functions that take an http.Handler and return an http.Handler. If you have a function that doesn't match this signature, you can wrap it manually.

    Example of wrapping a function to match the required signature:

    func myStripPrefix(h http.Handler) http.Handler {
        return http.StripPrefix("/old", h)
    }
  4. Chain middleware to an http.Handler with Then()

    master

    The Then() method applies the middleware in the chain to the provided http.Handler. The middleware are applied in the order they were passed to New(), such that the first middleware in the list is the first one to receive the request.

    Example: New(m1, m2, m3).Then(h) is equivalent to m1(m2(m3(h))).

    If nil is passed to Then(), it uses http.DefaultServeMux as the final handler.

  5. Chain middleware to an http.HandlerFunc with ThenFunc()

    master
    The ThenFunc() method works identically to Then(), but accepts an http.HandlerFunc instead of an http.Handler. This is a convenience method to avoid manual casting.
  6. Create a new middleware Chain with New()

    master
    Use alice.New() to create a new Chain. A Chain is an immutable list of Constructor functions. The constructors are not executed when the chain is created; they are only called when you call Then() or ThenFunc() to wrap a handler.
  7. Extend a chain with Extend()

    master

    The Extend() method returns a new Chain that includes the original constructors followed by all the constructors from another Chain. The original chains remain unchanged.

    stdChain := alice.New(m1, m2)
    ext1Chain := alice.New(m3, m4)
    ext2Chain := stdChain.Extend(ext1Chain)
    // requests in ext2Chain go: m1 -> m2 -> m3 -> m4
  8. Define a middleware Constructor

    master

    In alice, a middleware is represented by a Constructor type. This is a function that takes an http.Handler and returns a new http.Handler wrapping it.

    type Constructor func(http.Handler) http.Handler