diff --git a/examples/petstore-expanded/gorilla/api/cfg.yaml b/examples/petstore-expanded/gorilla/api/cfg.yaml index 7f1a2d759c..8ead7a60de 100644 --- a/examples/petstore-expanded/gorilla/api/cfg.yaml +++ b/examples/petstore-expanded/gorilla/api/cfg.yaml @@ -4,3 +4,5 @@ generate: models: true embedded-spec: true output: petstore.gen.go +compatibility: + apply-gorilla-middleware-first-to-last: true diff --git a/examples/petstore-expanded/gorilla/api/petstore.gen.go b/examples/petstore-expanded/gorilla/api/petstore.gen.go index deac9824ad..b55ecd0142 100644 --- a/examples/petstore-expanded/gorilla/api/petstore.gen.go +++ b/examples/petstore-expanded/gorilla/api/petstore.gen.go @@ -114,8 +114,8 @@ func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Reque siw.Handler.FindPets(w, r, params) } - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + handler = siw.HandlerMiddlewares[i](handler) } handler(w, r.WithContext(ctx)) @@ -129,8 +129,8 @@ func (siw *ServerInterfaceWrapper) AddPet(w http.ResponseWriter, r *http.Request siw.Handler.AddPet(w, r) } - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + handler = siw.HandlerMiddlewares[i](handler) } handler(w, r.WithContext(ctx)) @@ -155,8 +155,8 @@ func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Requ siw.Handler.DeletePet(w, r, id) } - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + handler = siw.HandlerMiddlewares[i](handler) } handler(w, r.WithContext(ctx)) @@ -181,8 +181,8 @@ func (siw *ServerInterfaceWrapper) FindPetByID(w http.ResponseWriter, r *http.Re siw.Handler.FindPetByID(w, r, id) } - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + handler = siw.HandlerMiddlewares[i](handler) } handler(w, r.WithContext(ctx)) diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 1400c3c740..afa4fc5020 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -69,6 +69,11 @@ type CompatibilityOptions struct { // This resolves the behavior such that middlewares are chained in the order they are invoked. // Please see https://github.com/deepmap/oapi-codegen/issues/786 ApplyChiMiddlewareFirstToLast bool `yaml:"apply-chi-middleware-first-to-last,omitempty"` + // Our generated code for gorilla/mux has historically inverted the order in which gorilla/mux middleware is + // applied such that the last invoked middleware ends up executing first in the middlewares chain + // This resolves the behavior such that middlewares are chained in the order they are invoked. + // Please see https://github.com/deepmap/oapi-codegen/issues/841 + ApplyGorillaMiddlewareFirstToLast bool `yaml:"apply-gorilla-middleware-first-to-last,omitempty"` } // OutputOptions are used to modify the output code in some way. diff --git a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl index a72713b3a6..9752c9f690 100644 --- a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl @@ -177,9 +177,15 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ siw.Handler.{{.OperationId}}(w, r{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) } + {{if opts.Compatibility.ApplyGorillaMiddlewareFirstToLast}} + for i := len(siw.HandlerMiddlewares) -1; i >= 0; i-- { + handler = siw.HandlerMiddlewares[i](handler) + } + {{else}} for _, middleware := range siw.HandlerMiddlewares { handler = middleware(handler) } + {{end}} handler(w, r.WithContext(ctx)) }