Search code examples
gogo-alice

Build fails when passing custom middleware type to alice.New() function


This is about an error I am getting while I try to build my application.

I use Gorilla mux as a router and Alice for chaining the middlewares.

And I defined a custom type named 'Middleware' with the following signature;

type Middleware func(http.Handler) http.Handler

And following is the code where I chain the middlewares and the handler, using Alice.

if len(config.Middlewares()) > 0 {
   subRouter.Handle(config.Path(), alice.New(config.Middlewares()...).Then(config.Handler())).Methods(config.Methods()...).Schemes(config.Schemes()...)
}

But when I try to build, I get the following error in the console;

infrastructure/router.go:88:63: cannot use config.Middlewares() (type []Middleware) as type []alice.Constructor in argument to alice.New

I'd checked the code for alice.Constructor. It also has the same signature as my Middleware type.

I am using Go 1.13, and the following version of Alice.

github.com/justinas/alice v1.2.0

Can you please help me to sort out this?


Solution

  • alice.Constructor has the same signature BUT it is defined as another type. So you can't just use it.

    Watch this https://www.youtube.com/watch?v=Vg603e9C-Vg It has a good explanation.

    What you can do is use type aliases Like this:

    var Middleware = alice.Constructor
    

    Will look like this:

    Before:

    
    func timeoutHandler(h http.Handler) http.Handler {
        return http.TimeoutHandler(h, 1*time.Second, "timed out")
    }
    
    func myApp(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello world!"))
    }
    
    type Middleware func(http.Handler) http.Handler
    
    func main() {
        middlewares := []Middleware{timeoutHandler}
    
        http.Handle("/", alice.New(middlewares...).ThenFunc(myApp))
    }
    
    

    After:

    func timeoutHandler(h http.Handler) http.Handler {
        return http.TimeoutHandler(h, 1*time.Second, "timed out")
    }
    
    func myApp(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello world!"))
    }
    
    type Middleware = alice.Constructor
    
    func main() {
        middlewares := []Middleware{timeoutHandler}
    
        http.Handle("/", alice.New(middlewares...).ThenFunc(myApp))
    }