middleware.go 2.1 KB

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