oapi-codegen / oapi-codegen

Generate Go client and server boilerplate from OpenAPI 3 specifications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clarify absence of `OapiResponseValidator` and make middleware options more specific

Antonboom opened this issue · comments

Hello!

OapiRequestValidatorWithOptions has ambiguous API. Not all fields from openapi3filter.Options are used:

oapimdlwr.OapiRequestValidatorWithOptions(v1Swagger, &oapimdlwr.Options{
    Options: openapi3filter.Options{
        ExcludeRequestBody:  false,
        ExcludeResponseBody: true, // Doesn't matter!
        AuthenticationFunc:  openapi3filter.NoopAuthenticationFunc,
    },
})

My bad, but I was sure that the oapi-codegen could validate the response.
And was surprised to find that there is no use of the openapi3filter.ValidateResponse.

Hi Anton. I've been looking at this too as I'm also interested in response validation. It looks as if the options struct is imported from a different package github.com/getkin/kin-openapi which the middleware in this package uses to carry out validations. As you mention the response-related flags are not used into the RequestValidator.

It looks like it would be useful to either:

  • Extend the OapiRequestValidator{WithOptions} methods to include response validation when specified (although this would make the name misleading and create a breaking change)
  • Add method(s) OapiResponseValidator{WithOptions} which would call the kin-openapi response validation code

i'm going to look at creating this middleware, will update here when i have a PR ready

i've got the bones of this for gin (which is the http router we use) but it could easily be repurposed to different implementations oapi-codegen/gin-middleware#13

Thanks for the work on this! What use cases do you have for this? Would be interested to know just so I can gauge how it's going to be used.

Ie should it be configurable that it actually stops the malformed response going to the caller or should it just ie log?

For testing purposes I wrote https://pkg.go.dev/openapi.tanna.dev/go/validator which may be helpful but if you want the full app integrated then the proposed solution looks good.

Essentially this is for use in conjunction with the OapiRequestValidator, which actually validates incoming requests against the schema. If you have defined responses in an OAS schema, and the responses your application responds with do not conform to that contract, then ultimately your API is breaking its contract, and I would view this as a server error (hence the 500 status code). It does somewhat defeat the point of defining responses in an API spec if the endpoints can return data which doesn't obey the schema.

Having it be configurable in that sense is not something I'd considered, but would be desirable. For some use cases, having such a strict all or nothing approach to response validation is overkill, as the consumer might not be interested in the areas where the schema is violated. So I can get behind providing the option of hooking in with a log-only implementation.

Testing schema compliance before releases is a sensible thing to do in its own right, and ultimately just as (if not more) important as having this type of middleware running in the deployed API. That tool looks like a really good approach, I'll definitely check it out.

I realise actually that it readily configurable using the ErrorHandler field in the options, which can be used to override the status code when the response violates the schema. This is also where any custom logging can be set up.

To maintain the consistency with the request middleware, I'd say this is the best approach for this.