2

I'm working on a custom middleware for traefik that serves as a base for other sub-middlewares. Each sub-middleware implements an interface and has its own config structure. Here's an outline of my current setup:

// Sub-middleware interface
type INETMiddleware interface {
    ServeHTTP(w http.ResponseWriter, r *http.Request) *sperrors.Error
}

// Configuration for the middleware
type INETConfig struct {
    *INETSession
    *INETGeoBlock
    *INETAntibot
    *INETHelloWorld
    InternalErrorHTMLFilePath string `json:"internalErrorHTMLFilePath" toml:"internalErrorHTMLFilePath" yaml:"internalErrorHTMLFilePath"`
}

// Example sub-middleware config
type INETHelloWorld struct {
    Message string `json:"message" toml:"message" yaml:"message"`
}

Each sub-middleware is initialized and executed in the main middleware like this:


    BaseMiddleware struct {
        next http.Handler
        name string

        mws                   []INETMiddleware
        internalErrorTemplate string
        logger                *zerolog.Logger
    }

func New(
    ctx context.Context,
    next http.Handler,
    cfg dynamic.INETConfig,
    name string,
) (*BaseMiddleware, error) {
    mws := []INETMiddleware{}
    // Adding sub-middleware
    if cfg.INETAntibot != nil {
        mw, err := antibot.New(ctx, next, *cfg.INETAntibot, name, cacheService, sessionService)
        if err != nil {
            return nil, err
        }
        mws = append(mws, mw)
    }
    // More sub-middleware can be added here...
    return &BaseMiddleware{next: next, mws: mws, ...}, nil
}


func (b *BaseMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    for _, mw := range b.mws {
        err := mw.ServeHTTP(w, r)
        if err == nil {
            continue
        }

        if err.IsHandled() {
            return
        }

        b.logger.Err(err).Msgf("middleware: %s", err)
        b.handleInternalServeHTTP(w)
        return
    }
    b.next.ServeHTTP(w, r)
}

The problem is that i have to manually add each sub-middleware by checking the config and appending it to the list. This make it tedious to add new sub-middleware in the future.

Goal:

  1. Make the process of adding sub-middleware more modular and less repetitive.
  2. Each sub-middleware should have its own config structure and be easily added/removed without modifying the main middleware much.

Questions:

  • How can I refactor this setup to make it easier to add new sub-middleware?
  • Are there any patterns or best practices in Go or middleware design that could simplify this process?

Thanks for your help!

I try to implement chain of responsibility pattern middleware but the current i see its does not differ much

and read some links https://drstearns.github.io/tutorials/gomiddleware/ https://medium.com/@matryer/writing-middleware-in-golang-and-how-go-makes-it-so-much-fun-4375c1246e81

But dont know how to implment this will make its better

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.