Connexion response validation

121 views Asked by At

Using the latest stable version of Connexion (2.14.2) the documentation states that response validation can be used to "validate all the responses using jsonschema and is specially useful during development"

With the following basic app and openapi specification, the validation mechanism doesn't pick up that the response contains a JSON key/value pair that isn't defined in the schema:

openapi: "3.0.0"

info:
  title: Hello World
  version: "1.0"
servers:
  - url: /openapi

paths:
  /version:
    get:
      operationId: app.version
      responses:
        200:
          description: Version
          content:
            application/json:
              schema:
                type: object
                properties:
                  version:
                    description: Version
                    example: '1.2.3'
                    type: string
import connexion


def version() -> dict:
  return {
    'foo': 'bar',
    'version': '1.2.3'
  }

app = connexion.FlaskApp(__name__)
app.add_api('openapi.yaml', validate_responses=True)
app.run(port=3000)

Validation appears to be working generally, by that I mean I can change the definition of the version function to the following and a validation error will be produced:

def version() -> dict:
  return {
    'foo': 'bar',
    'version': 5
  }
{
  "detail": "5 is not of type 'string'\n\nFailed validating 'type' in schema['properties']['version']:\n    {'description': 'Version', 'example': '1.2.3', 'type': 'string'}\n\nOn instance['version']:\n    5",
  "status": 500,
  "title": "Response body does not conform to specification",
  "type": "about:blank"
}

Is there something I'm doing wrong here or does Connexion/jsonschema not perform validation of extraneous (or unknown) key/value pairs?

1

There are 1 answers

0
Jeremy Fiel On BEST ANSWER

JSON Schema is a constraints based language, and anything you don't specify / constrain is allowable

In your case, the foo property is not defined and thus, ignored; there are no constraints applied to it. If you want to prevent other properties in your schema, you can use additionalProperties: false

openapi: "3.0.3"

info:
  title: Hello World
  version: "1.0"
servers:
  - url: /openapi

paths:
  /version:
    get:
      operationId: app.version
      responses:
        200:
          description: Version
          content:
            application/json:
              schema:
                additionalProperties: false
                type: object
                properties:
                  version:
                    description: Version
                    example: '1.2.3'
                    type: string

Then your instance will fail

def version() -> dict:
  return {
    'foo': 'bar',
    'version': 5
  }

You can learn all about JSON Schema in this getting started guide