Skip to content

Any OpenAPI validator that properly validates discriminator against data? #2141

@mewalig

Description

@mewalig

I would like to use an OpenAPI schema with a discriminator, then validate some input againts the schema. Thought this would be really easy-- there are so many validators out there that say they have discriminator support... and none of them I've tried so far worked! Seems like a fundamental task that anyone working with OpenAPI would need to perform, so maybe there's obvious and easy solution and I'm just not seeing it or I'm doing something wrong (maybe the spec I am using is flawed?)

In particular, I would like to do the following:

  1. Given an OpenAPI spec that includes a POST request body using a schema with a discriminator, start a localhost web server on any port
  2. Send a POST request using curl to the above service, and receive an accept/reject response based on whether the POSTed data conformed to the request body schema

I have tried the following, and in each case, I got the same result: validation worked fine in general, but failed to throw an error when the mapped schema and the discriminator value did not match (see specific example below)

The specific test case I used is as follows:

  • the spec describes a polymorphic object called Object, which has two subclasses: "obj1" and "obj2", each with a corresponding "properties" object that contains "property1a" & "property1b" in the case of "obj1", and "property2a" & "property2b" in the case of "obj2"
  • the test cases are i) a valid object, and ii) an invalid object that contains type "obj2" but properties corresponding to the obj1 subclass properties schema

Test Case 1 (valid data):

{
  "id": "hi",
  "type": "obj1",
  "properties": {
    "property1a": 1,
    "property1b": 2
  }
}

curl command:

curl -X POST -k 'http://localhost:3000/v1/object/hi' -H 'Content-type: application/json' --data '{"id":"hi","type":"obj1","properties":{"property1a":1,"property1b":2}}'

Test Case 2 (invalid data, validator properly rejects):

{
  "id": "hi",
  "type": "obj1",
  "properties": {
    "nonexistent_property": 1,
    "property1b": 2
  }
}

Notice that nonexistent_property is invalid. All of the validators I tried correctly reject this

curl -X POST -k 'http://localhost:3000/v1/object/hi' -H 'Content-type: application/json' --data '{"id":"hi","type":"obj2","properties":{"nonexistent_property":1,"property1b":2}}'

Test Case 3 (validator should throw an error, but does not!):

{
  "id": "hi",
  "type": "obj2",
  "properties": {
    "property1a": 1,
    "property1b": 2
  }
}

Notice that the type is obj2 but the properties are those corresponding to obj1. None of the validators reject this-- but they should, right?

curl command:

curl -X POST -k 'http://localhost:3000/v1/object/hi' -H 'Content-type: application/json' --data '{"id":"hi","type":"obj2","properties":{"property1a":1,"property1b":2}}'

YAML:

  openapi: "3.0.0"
  info: 
    version: "1.0.0"
    title: "Discriminator example"
    license: 
      name: "MIT"
  servers: 
    - url: "http://localhost/v1"
  components: 
    schemas: 
      Error: 
        type: "object"
        required: 
          - "code"
          - "message"
        properties: 
          code: 
            type: "integer"
            format: "int32"
          message: 
            type: "string"
      Object1Properties: 
        type: "object"
        required: 
          - "property1a"
          - "property1b"
        properties: 
          property1a: 
            type: "string"
          property1b: 
            type: "string"
      Object2Properties: 
        type: "object"
        required: 
          - "property2a"
          - "property2b"
        properties: 
          property2a: 
            type: "string"
          property2b: 
            type: "string"
      Object: 
        type: "object"
        required: 
          - "id"
          - "type"
          - "properties"
        properties: 
          id: 
            type: "string"
          type: 
            type: "string"
            enum: 
              - "obj1"
              - "obj2"
          properties: 
            oneOf: 
              - 
                $ref: "#/components/schemas/Object1Properties"
              - 
                $ref: "#/components/schemas/Object2Properties"
            discriminator: 
              propertyName: "type"
              mapping: 
                obj1: "#/components/schemas/Object1Properties"
                obj2: "#/components/schemas/Object2Properties"
    requestBodies:
      Object: 
        description: "Object schema in request body"
        content: 
          application/json: 
            schema: 
              $ref: "#/components/schemas/Object"
    parameters: 
      objectId: 
        name: "objectId"
        in: "path"
        required: true
        description: "Id of the object"
        schema: 
          type: "string"
    responses: 
      defaultError: 
        description: "Unexpected error"
        content: 
          application/json: 
            schema: 
              $ref: "#/components/schemas/Error"
  paths: 
    /object/{objectId}:
      post:
        summary: "Create an object"
        operationId: "createObject"
        parameters: 
          - 
            $ref: "#/components/parameters/objectId"
        tags: 
          - "objects"
        requestBody: 
          $ref: "#/components/requestBodies/Object"
        responses: 
          201: 
            description: "Object created"
            content: 
              application/json: 
                schema: 
                  $ref: "#/components/schemas/Object"
          default: 
            $ref: "#/components/responses/defaultError"

Example of validator server using express-openapi-validator is attached.
validation_server.zip

Any help is much appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions