Skip to content

Instantly share code, notes, and snippets.

@sidgwick
Created March 20, 2024 07:23
Show Gist options
  • Save sidgwick/8baee8cf585efcd1018fd938cc1fd0b2 to your computer and use it in GitHub Desktop.
Save sidgwick/8baee8cf585efcd1018fd938cc1fd0b2 to your computer and use it in GitHub Desktop.
Golang Middleware example
package main
import (
"context"
"fmt"
)
type Middleware = func(ctx context.Context) (bool, error)
type MiddlewareBuilder = func(next Middleware) Middleware
type Manager struct {
middleware []MiddlewareBuilder
}
func NewManager() *Manager {
return &Manager{
middleware: []MiddlewareBuilder{},
}
}
func (m *Manager) Use(middleware MiddlewareBuilder) {
m.middleware = append(m.middleware, middleware)
}
func (m *Manager) Execute(ctx context.Context) (bool, error) {
realTask := func(ctx context.Context) (bool, error) {
fmt.Printf("execute done\n")
return true, nil
}
next := realTask
for i := len(m.middleware) - 1; i >= 0; i-- {
mb := m.middleware[i]
next = mb(next)
}
return next(ctx)
}
func Middleware1(next Middleware) Middleware {
return func(ctx context.Context) (bool, error) {
fmt.Printf("middleware 1 in\n")
ok, err := next(ctx)
if err != nil {
return ok, err
}
fmt.Printf("middleware 1 out\n")
return ok, nil
}
}
func Middleware2(next Middleware) Middleware {
return func(ctx context.Context) (bool, error) {
fmt.Printf("middleware 2 in\n")
ok, err := next(ctx)
if err != nil {
return ok, err
}
fmt.Printf("middleware 2 out\n")
return ok, nil
}
}
func Middleware3(next Middleware) Middleware {
return func(ctx context.Context) (bool, error) {
fmt.Printf("middleware 3 in\n")
ok, err := next(ctx)
if err != nil {
return ok, err
}
fmt.Printf("middleware 3 out\n")
return ok, nil
}
}
func main() {
ctx := context.Background()
m := NewManager()
m.Use(Middleware1)
m.Use(Middleware2)
m.Use(Middleware3)
res, err := m.Execute(ctx)
fmt.Printf("result=%v, error=%v", res, err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment