src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

middleware.go (2120B)


      1 package middleware
      2 
      3 import (
      4 	"context"
      5 )
      6 
      7 // Handler provides the interface for performing the logic to obtain an output,
      8 // or error for the given input.
      9 type Handler interface {
     10 	// Handle performs logic to obtain an output for the given input. Handler
     11 	// should be decorated with middleware to perform input specific behavior.
     12 	Handle(ctx context.Context, input interface{}) (
     13 		output interface{}, metadata Metadata, err error,
     14 	)
     15 }
     16 
     17 // HandlerFunc provides a wrapper around a function pointer to be used as a
     18 // middleware handler.
     19 type HandlerFunc func(ctx context.Context, input interface{}) (
     20 	output interface{}, metadata Metadata, err error,
     21 )
     22 
     23 // Handle invokes the underlying function, returning the result.
     24 func (fn HandlerFunc) Handle(ctx context.Context, input interface{}) (
     25 	output interface{}, metadata Metadata, err error,
     26 ) {
     27 	return fn(ctx, input)
     28 }
     29 
     30 // Middleware provides the interface to call handlers in a chain.
     31 type Middleware interface {
     32 	// ID provides a unique identifier for the middleware.
     33 	ID() string
     34 
     35 	// Performs the middleware's handling of the input, returning the output,
     36 	// or error. The middleware can invoke the next Handler if handling should
     37 	// continue.
     38 	HandleMiddleware(ctx context.Context, input interface{}, next Handler) (
     39 		output interface{}, metadata Metadata, err error,
     40 	)
     41 }
     42 
     43 // decoratedHandler wraps a middleware in order to to call the next handler in
     44 // the chain.
     45 type decoratedHandler struct {
     46 	// The next handler to be called.
     47 	Next Handler
     48 
     49 	// The current middleware decorating the handler.
     50 	With Middleware
     51 }
     52 
     53 // Handle implements the Handler interface to handle a operation invocation.
     54 func (m decoratedHandler) Handle(ctx context.Context, input interface{}) (
     55 	output interface{}, metadata Metadata, err error,
     56 ) {
     57 	return m.With.HandleMiddleware(ctx, input, m.Next)
     58 }
     59 
     60 // DecorateHandler decorates a handler with a middleware. Wrapping the handler
     61 // with the middleware.
     62 func DecorateHandler(h Handler, with ...Middleware) Handler {
     63 	for i := len(with) - 1; i >= 0; i-- {
     64 		h = decoratedHandler{
     65 			Next: h,
     66 			With: with[i],
     67 		}
     68 	}
     69 
     70 	return h
     71 }