middleware

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

README

Release Reference DeepWiki Test

Insights Insights

go-middleware

Server-side and client-side middleware chaining library for Go.

Features

  • HTTP server-side middleware chain
  • HTTP client-side middleware chain
  • Powerful chaining
  • Simple

HTTP server-side middleware pattern in go:

// ServerMiddleware is the server side middleware.
type ServerMiddleware interface {
    ServerMiddleware(next http.Handler) http.Handler
}

// ServerMiddlewareFunc type is an adapter to allow the
// use of ordinary function as server middleware.
type ServerMiddlewareFunc func(next http.Handler) http.Handler

func (f ServerMiddlewareFunc) ServerMiddleware(next http.Handler) http.Handler {
    return f(next)
}

HTTP client-side middleware pattern in go:

// ClientMiddleware is the client side middleware.
type ClientMiddleware interface {
    ClientMiddleware(next http.RoundTripper) http.RoundTripper
}

// ClientMiddlewareFunc type is an adapter to allow the
// use of ordinary function as client middleware.
type ClientMiddlewareFunc func(next http.RoundTripper) http.RoundTripper

func (f ClientMiddlewareFunc) ClientMiddleware(next http.RoundTripper) http.RoundTripper {
    return f(next)
}

Usages

Server-side middleware chaining

This example applies logging middleware and timeout middleware to the server's hello handler. Server-side middlewares can be easily appended to the chain.

func main() {
    chain := middleware.ServerMiddlewareChain{} // Create an empty chain.
    chain = chain.AppendFunc(logging, timeout)  // Append middlewares.
    handler := chain.TerminateFunc(hello)       // Finalize with the handler.

    err := http.ListenAndServe(":8080", handler)
    if err != nil {
        panic(err)
    }
}

// logging prints access info.
func logging(next http.Handler) http.Handler {
    return middleware.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.Proto, r.Method, r.RequestURI)
        next.ServeHTTP(w, r)
    })
}

// timeout applies request timeout of 2 seconds.
func timeout(next http.Handler) http.Handler {
    return http.TimeoutHandler(next, time.Second, "request timeout")
}

// hello says hello after sleep. Maybe timeout.
func hello(w http.ResponseWriter, r *http.Request) {
    sleep := time.Second * time.Duration(rand.IntN(5))
    log.Println("sleeping:", sleep)
    time.Sleep(sleep)
    _, _ = w.Write([]byte("ok"))
}

The following methods are defined for the middleware chain. See the godoc for details.

// The middleware chain is a middleware itself.
func ServerMiddleware(next http.Handler) http.Handler

// Terminate the chain with the handler.
func Terminate(h http.Handler) http.Handler
func TerminateFunc(h http.HandlerFunc) http.Handler

// Add middlewares to the chain.
func Append(ms ...ServerMiddleware) ServerMiddlewareChain
func AppendFunc(ms ...ServerMiddlewareFunc) ServerMiddlewareChain
func Prepend(ms ...ServerMiddleware) ServerMiddlewareChain
func PrependFunc(ms ...ServerMiddlewareFunc) ServerMiddlewareChain
func InsertAt(index int, ms ...ServerMiddleware) ServerMiddlewareChain
func InsertAtFunc(index int, ms ...ServerMiddlewareFunc) ServerMiddlewareChain
func InsertBeforeAll(ms ...ServerMiddleware) ServerMiddlewareChain
func InsertBeforeAllFunc(ms ...ServerMiddlewareFunc) ServerMiddlewareChain
func InsertAfterAll(ms ...ServerMiddleware) ServerMiddlewareChain
func InsertAfterAllFunc(ms ...ServerMiddlewareFunc) ServerMiddlewareChain
func InsertAll(ms ...ServerMiddleware) ServerMiddlewareChain
func InsertAllFunc(ms ...ServerMiddlewareFunc) ServerMiddlewareChain
Client-side middleware chaining

This example applies logging middleware and timeout middleware to the http client. Here a dummy round tripper is used as the final round tripper.. Client-side middlewares can be easily appended to the chain.


func main() {
    chain := middleware.ClientMiddlewareChain{} // Create an empty chain.
    chain = chain.AppendFunc(logging, timeout)  // Append middlewares.
    roundTripper := chain.TerminateFunc(hello)  // Finalize with the handler.

    r, _ := http.NewRequest(http.MethodGet, "http://localhost:8080/hello", nil)
    w, err := roundTripper.RoundTrip(r)
    if err != nil {
        log.Println(err)
    } else {
        body, _ := io.ReadAll(w.Body)
        log.Println(string(body))
    }
}

// logging prints request info.
func logging(next http.RoundTripper) http.RoundTripper {
    return middleware.RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
        log.Println(r.Proto, r.Method, r.RequestURI)
        return next.RoundTrip(r)
    })
}

// timeout applies request timeout of 2 seconds.
func timeout(next http.RoundTripper) http.RoundTripper {
    return middleware.RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
        ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
        defer cancel()
        r = r.WithContext(ctx)
        return next.RoundTrip(r)
    })
}

// hello returns dummy response.
func hello(r *http.Request) (*http.Response, error) {
    sleep := time.Second * time.Duration(rand.IntN(5))
    log.Println("sleeping:", sleep)
    select {
    case <-r.Context().Done():
        return nil, r.Context().Err()
    case <-time.After(sleep):
        return &http.Response{
            StatusCode: http.StatusOK,
            Body:       io.NopCloser(strings.NewReader("hello")),
        }, nil
    }
}

The following methods are defined for the middleware chain. See the godoc for details.

// The middleware chain is a middleware itself.
func ClientMiddleware(next http.RoundTripper) http.RoundTripper

// Terminate the chain with the round tripper.
func Terminate(rt http.RoundTripper) http.RoundTripper
func TerminateFunc(rt RoundTripperFunc) http.RoundTripper

// Add middlewares to the chain.
func Append(ms ...ClientMiddleware) ClientMiddlewareChain
func AppendFunc(ms ...ClientMiddlewareFunc) ClientMiddlewareChain
func Prepend(ms ...ClientMiddleware) ClientMiddlewareChain
func PrependFunc(ms ...ClientMiddlewareFunc) ClientMiddlewareChain
func InsertAt(index int, ms ...ClientMiddleware) ClientMiddlewareChain
func InsertAtFunc(index int, ms ...ClientMiddlewareFunc) ClientMiddlewareChain
func InsertBeforeAll(ms ...ClientMiddleware) ClientMiddlewareChain
func InsertBeforeAllFunc(ms ...ClientMiddlewareFunc) ClientMiddlewareChain
func InsertAfterAll(ms ...ClientMiddleware) ClientMiddlewareChain
func InsertAfterAllFunc(ms ...ClientMiddlewareFunc) ClientMiddlewareChain
func InsertAll(ms ...ClientMiddleware) ClientMiddlewareChain
func InsertAllFunc(ms ...ClientMiddlewareFunc) ClientMiddlewareChain

Docs & Examples

References

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHandler

func NewHandler(h http.Handler, ms ...ServerMiddleware) http.Handler

NewHandler returns a http handler with server-side middlewares.

func NewRoundTripper

func NewRoundTripper(rt http.RoundTripper, ms ...ClientMiddleware) http.RoundTripper

NewRoundTripper returns a http round tripper with client-side middlewares.

Types

type ClientMiddleware

type ClientMiddleware interface {
	ClientMiddleware(next http.RoundTripper) http.RoundTripper
}

ClientMiddleware is the client side middleware.

type ClientMiddlewareChain

type ClientMiddlewareChain []ClientMiddleware

ClientMiddlewareChain is the client-side middleware chain. ClientMiddlewareChain is a ClientMiddleware itself.

func (ClientMiddlewareChain) Append

Append appends middlewares to the chain. Given middlewares are added to the end of the chain.

func (ClientMiddlewareChain) AppendFunc

AppendFunc appends middleware functions to the chain. Given middlewares are added to the end of the chain.

func (ClientMiddlewareChain) ClientMiddleware

func (c ClientMiddlewareChain) ClientMiddleware(next http.RoundTripper) http.RoundTripper

ClientMiddleware implements ClientMiddleware.

func (ClientMiddlewareChain) InsertAfterAll

InsertAfterAll inserts given middlewares after all middlewares in the chain. Middlewares are inserted at the index of 1 to n. Calling InsertAfterAll to an empty chain returns an empty chain also.

insert ×      ○      ○      ○      ○      ○       ○
       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ClientMiddlewareChain) InsertAfterAllFunc

InsertAfterAllFunc inserts given middleware functions after all middlewares in the chain.

func (ClientMiddlewareChain) InsertAll

InsertAll inserts given middlewares between each middlewares in the chain. Middlewares are inserted at the index of 0 to n. Calling InsertAll to an empty chain returns an empty chain also.

insert ○      ○      ○      ○      ○      ○       ○
       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ClientMiddlewareChain) InsertAllFunc

InsertAllFunc inserts given middleware functions between each middlewares in the chain.

func (ClientMiddlewareChain) InsertAt

InsertAt inserts middlewares at the position of index. For index<=0, middlewares are added at the beginning of the chain. For index>=len(c), middlewares are added at the end of the chain.

       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ClientMiddlewareChain) InsertAtFunc

InsertAtFunc inserts middleware functions at the position of index.

func (ClientMiddlewareChain) InsertBeforeAll

InsertBeforeAll inserts given middlewares before all middlewares in the chain. Middlewares are inserted at the index of 0 to n-1. Calling InsertBeforeAll to an empty chain returns an empty chain also.

insert ○      ○      ○      ○      ○      ○       ×
       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ClientMiddlewareChain) InsertBeforeAllFunc

InsertBeforeAllFunc inserts given middleware functions before all middlewares in the chain.

func (ClientMiddlewareChain) Prepend

Prepend prepends middlewares to the chain. Given middlewares are added to the front of the chain.

func (ClientMiddlewareChain) PrependFunc

PrependFunc prepends middleware functions to the chain. Given middlewares are added to the front of the chain.

func (ClientMiddlewareChain) Terminate

Terminate returns a round tripper with the middleware chain terminated by rt.

func (ClientMiddlewareChain) TerminateFunc

TerminateFunc returns a round tripper with the middleware chain terminated by rt.

type ClientMiddlewareFunc

type ClientMiddlewareFunc func(next http.RoundTripper) http.RoundTripper

ClientMiddlewareFunc type is an adapter to allow the use of ordinary function as client middleware. If f is a function with the appropriate signature, ClientMiddlewareFunc(f) is ClientMiddleware that calls f.

Example:

var m ClientMiddleware
m = ClientMiddlewareFunc(func(next http.RoundTripper) http.RoundTripper {
	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
		// Some process.
		return next.RoundTrip(r)
	})
})

func (ClientMiddlewareFunc) ClientMiddleware

func (f ClientMiddlewareFunc) ClientMiddleware(next http.RoundTripper) http.RoundTripper

type HandlerFunc

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

HandlerFunc type is an adapter to allow the use of ordinary function as HTTP handlers. If f is a function with the appropriate signature, HandlerFunc(f) is http.Handler that calls f. HandlerFunc is the same as http.HandlerFunc.

Example:

var h http.Handler
h = HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("ok"))
})

func (HandlerFunc) ServeHTTP

func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)

type RoundTripperFunc

type RoundTripperFunc func(*http.Request) (*http.Response, error)

RoundTripperFunc type is an adapter to allow the use of ordinary function as HTTP round tripper. If f is a function with the appropriate signature, RoundTripperFunc(f) is http.RoundTripper that calls f.

Example:

var r http.RoundTripper
r = RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
	// Some process.
	return http.DefaultTransport.RoundTrip(r)
})

func (RoundTripperFunc) RoundTrip

func (f RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error)

type ServerMiddleware

type ServerMiddleware interface {
	ServerMiddleware(next http.Handler) http.Handler
}

ServerMiddleware is the server side middleware.

type ServerMiddlewareChain

type ServerMiddlewareChain []ServerMiddleware

ServerMiddlewareChain is the server-side middleware chain. ServerMiddlewareChain is a ServerMiddleware itself.

func (ServerMiddlewareChain) Append

Append appends middlewares to the chain. Given middlewares are added to the end of the chain.

func (ServerMiddlewareChain) AppendFunc

AppendFunc appends middleware functions to the chain. Given middlewares are added to the end of the chain.

func (ServerMiddlewareChain) InsertAfterAll

InsertAfterAll inserts given middlewares after all middlewares in the chain. Middlewares are inserted at the index of 1 to n. Calling InsertAfterAll to an empty chain returns an empty chain also.

insert ×      ○      ○      ○      ○      ○       ○
       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ServerMiddlewareChain) InsertAfterAllFunc

InsertAfterAllFunc inserts given middleware functions after all middlewares in the chain.

func (ServerMiddlewareChain) InsertAll

InsertAll inserts given middlewares between each middlewares in the chain. Middlewares are inserted at the index of 0 to n. Calling InsertAll to an empty chain returns an empty chain also.

insert ○      ○      ○      ○      ○      ○       ○
       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ServerMiddlewareChain) InsertAllFunc

InsertAllFunc inserts given middleware functions between each middlewares in the chain.

func (ServerMiddlewareChain) InsertAt

InsertAt inserts middlewares at the position of index. For index<=0, middlewares are added at the beginning of the chain. For index>=len(c), middlewares are added at the end of the chain.

       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ServerMiddlewareChain) InsertAtFunc

InsertAtFunc inserts middleware functions at the position of index.

func (ServerMiddlewareChain) InsertBeforeAll

InsertBeforeAll inserts given middlewares before all middlewares in the chain. Middlewares are inserted at the index of 0 to n-1. Calling InsertBeforeAll to an empty chain returns an empty chain also.

insert ○      ○      ○      ○      ○      ○       ×
       ┌──────┬──────┬──────┬──────┬─────┬────────┐
m.w.   │ m[0] │ m[1] │ m[2] │ m[3] │ ... │ m[n-1] │
       ├──────┼──────┼──────┼──────┼─────┼────────┤
       ↑      ↑      ↑      ↑      ↑     ↑        ↑
index  0      1      2      3      4    n-1       n

func (ServerMiddlewareChain) InsertBeforeAllFunc

InsertBeforeAllFunc inserts given middleware functions before all middlewares in the chain.

func (ServerMiddlewareChain) Prepend

Prepend prepends middlewares to the chain. Given middlewares are added to the front of the chain.

func (ServerMiddlewareChain) PrependFunc

PrependFunc prepends middleware functions to the chain. Given middlewares are added to the front of the chain.

func (ServerMiddlewareChain) ServerMiddleware

func (c ServerMiddlewareChain) ServerMiddleware(next http.Handler) http.Handler

ServerMiddleware implements ServerMiddleware.

func (ServerMiddlewareChain) Terminate

Terminate returns a handler with the middleware chain terminated by h.

func (ServerMiddlewareChain) TerminateFunc

func (c ServerMiddlewareChain) TerminateFunc(h http.HandlerFunc) http.Handler

TerminateFunc returns a handler with the middleware chain terminated by h.

type ServerMiddlewareFunc

type ServerMiddlewareFunc func(next http.Handler) http.Handler

ServerMiddlewareFunc type is an adapter to allow the use of ordinary function as server middleware. If f is a function with the appropriate signature, ServerMiddlewareFunc(f) is ServerMiddleware that calls f.

Example:

var m ServerMiddleware
m = ServerMiddlewareFunc(func(next http.Handler) http.Handler {
	return HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Some process.
		next.ServeHTTP(w, r)
	})
})

func (ServerMiddlewareFunc) ServerMiddleware

func (f ServerMiddlewareFunc) ServerMiddleware(next http.Handler) http.Handler

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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