Connexion: x-nullable support in response body validation

Created on 13 Apr 2017  ·  11Comments  ·  Source: zalando/connexion

Description

I want to x-nullable support in response body validation.

Expected behaviour

supporting response object incuding null value as property. such as this person schema.

definitions:
   person:
     properties:
       name:
         type: string
       nickname:
         type: string
          x-nullable: true

Actual behaviour

validation error (input data is null and schema has x-nullable=true). connexion's x-nullable support is not comprehensive.

Steps to reproduce

Additional info:

supporting x-nullable with jsonschema library(used by connexion) is like a below code.
https://gist.github.com/podhmo/2259fa63b58f6bbc26d618976b7662db

Most helpful comment

Any news on this?

All 11 comments

ResponseBodyValidator class can receive validator class.
https://github.com/zalando/connexion/blob/master/connexion/decorators/validation.py#L143

But in ResponseValidator calling this class without any keyword arguments..
https://github.com/zalando/connexion/blob/master/connexion/decorators/response.py#L42

work-around is define custom ResponseValidator(almost copy), and passing this custom class at validator_map.

http://connexion.readthedocs.io/en/latest/response.html?highlight=validator_map#custom-validator

Not just response, also request - in definitions, basically.

e.g.

    put:
      x-swagger-router-controller: api.pets
      operationId: updatePets
      summary: Updates a Pet
      parameters:
        - name: pet
          in: body
          required: true
          description: The Pet to update.
          schema:
            $ref: '#/definitions/Pet'

Some fields in the Pet should be nullable.

The definitions contents is pure JSON schema. It does not support vendor extension and is out of scope of OpenAPI specification. Maybe better find a workaround using jsonschema lib.

The validation should allow null as a value OR a schema validated object.

The idea is to check if it is null, and if not - run jsonschema and validate.

Makes sense to me.

Any news on this?

I'd like this too

Me too,...

Solution given in http://stackoverflow.com/a/22565006 uses jsonschema features, it's not compliant with swagger spec but it works for me:

definitions:
   person:
     properties:
       name:
         type: string
       nickname:
         type: ["string", "null"]

Here is some solution with patching existing jsonschema validator:

from connexion.decorators.validation import RequestBodyValidator
import jsonschema
import six


# via https://python-jsonschema.readthedocs.io/
def extend_with_nullable_support(validator_class):
    """Add support for null values in request body."""
    validate_properties = validator_class.VALIDATORS['properties']

    def nullable_support(validator, properties, instance, schema):
        null_properties = {}
        for property_, subschema in six.iteritems(properties):
            if property_ in instance and \
                    instance[property_] is None and \
                    subschema.get('x-nullable') is True:
                null_properties[property_] = instance.pop(property_)  # exclude from following validation

        for error in validate_properties(validator, properties, instance, schema):
            yield error

        instance.update(null_properties)
    return jsonschema.validators.extend(
        validator_class, {'properties': nullable_support})


Draft4ValidatorSupportNullable = extend_with_nullable_support(
    jsonschema.Draft4Validator)


class RequestBodyValidatorSupportNullable(RequestBodyValidator):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, validator=Draft4ValidatorSupportNullable, **kwargs)


validator_map = {
    'body': RequestBodyValidatorSupportNullable
}

And then add newly created validator to app:

connexion_app = connexion.App(__name__, validator_map=validator_map)

Maybe create a PR?

On Fri, Jun 15, 2018 at 8:23 PM, dmksnnk notifications@github.com wrote:

Here is some solution with patching existing jsonschema validator:

from connexion.decorators.validation import RequestBodyValidatorimport jsonschemaimport six

via https://python-jsonschema.readthedocs.io/def extend_with_nullable_support(validator_class):

"""Add support for null values in request body."""
validate_properties = validator_class.VALIDATORS['properties']

def nullable_support(validator, properties, instance, schema):
    for property_, subschema in six.iteritems(properties):
        if property_ in instance and \
         instance[property_] is None and \
         subschema.get('x-nullable') is True:
            instance.pop(property_)  # exclude from following validation

    for error in validate_properties(
            validator, properties, instance, schema):
        yield error

return jsonschema.validators.extend(
    validator_class, {'properties': nullable_support})

Draft4ValidatorSupportNullable = extend_with_nullable_support(
jsonschema.Draft4Validator)

class RequestBodyValidatorSupportNullable(RequestBodyValidator):
def __init__(self, args, *kwargs):
super().__init__(args, validator=Draft4ValidatorSupportNullable, *kwargs)

validator_map = {
'body': RequestBodyValidatorSupportNullable
}

And then add newly created validator to app:

connexion_app = connexion.App(__name__, validator_map=validator_map)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/zalando/connexion/issues/439#issuecomment-397688726,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADuPtChRbJlgWKRedYGHzeCuGOmxlufZks5t8-2jgaJpZM4M8SAS
.

Was this page helpful?
0 / 5 - 0 ratings