jeudi 23 avril 2020

Reducing boilerplate in a mux middlware and custom context implementation

I'm fairly new to Go and trying to create a middleware implementation in a gateway library that I'm building on top of mux. So far, I've come up up with this:

type (
    MyContext struct {
        // ...
    }

    APIGateway struct {
        mux *mux.Router
        ctx *MyContext
    }
)

type MiddlewareFunc func(*MyContext) func(http.Handler) http.Handler

func (a APIGateway) Use(mw MiddlewareFunc) {
    a.mux.Use(mw(ctx))
}

This works, but then I have to deal with a lot of boilerplate code. The simplest middleware implemented on this pattern has to have a minimum of two return statements and lot of incline function declaration.

func someMiddleware(ctx *MyContext) func(http.Handler) http.Handler {
    return func(handler http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // Application Logic here
            handler.ServeHTTP(w, r)
        })
    }
}

This quickly becomes a bigger problem when the middlware has to take some extra parameters since now it has to deal with three return statements:

func LogginMiddleware(c LoggerConfig) MiddlewareFunc {
    return func(ctx *MyContext) func(http.Handler) http.Handler {
        return func(handler http.Handler) http.Handler {
            return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                // ...
                handler.ServeHTTP(lrw, r)
                // ...
            })
        }
    }
}

Is there a way I can possibly reduce the involvement of boilerplate code?

Aucun commentaire:

Enregistrer un commentaire