Search code examples
gogo-gin

If I use multiple middleware in gin what is the order in which they are executed


If I use multiple middleware and I want to use output of mw1 in mw2 using ctx.Set and ctx.Get is there any defined order in which middleware are executed?

func main() {
    // Creates a router without any middleware by default
    r := gin.New()

    // Global middleware
    // Logger middleware will write the logs to gin.DefaultWriter even you set with GIN_MODE=release.
    // By default gin.DefaultWriter = os.Stdout
    r.Use(mw1)

    // Recovery middleware recovers from any panics and writes a 500 if there was one.
    r.Use(mw2)

    // Per route middleware, you can add as many as you desire.
    r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
}

For instance in above sniped is mw1 called first, or mw2 is? And is there a guarantee on their ordering?


Solution

  • They are executed in the order they are added to the router. That's why it is usually referred as middleware chain.

    As you can see from the signature of functions that take middleware args, as Use, Group, etc. middlewares have type HandlerFunc and they are added to the HandlersChain, which is defined as:

    type HandlersChain []HandlerFunc
    

    So you can assume that context values set in a previous middleware will be available in the subsequent ones:

    func main() {
        r := gin.New()
        r.Use(func(c *gin.Context) {
            c.Set("key", "foo")
        })
        
        r.Use(func(c *gin.Context) {
            fmt.Println(c.MustGet("key").(string)) // foo 
        })
    }