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 }
72