swagger-api / swagger-editor

Swagger Editor
https://editor.swagger.io
Apache License 2.0
8.88k stars 2.24k forks source link

SwaggerEditor@next: no validation against Incompatible types in schemas using `allOf` #3732

Closed mtovt closed 1 year ago

mtovt commented 1 year ago

Q&A (please complete the following information)

Content & configuration

Example Swagger/OpenAPI definition:

openapi: 3.0.1
info:
  title: incompatible types in allOf minimal example
  description: allOf example
  version: 0.1.0
servers:
  - url: 'https://example.com'
paths:
  '/foo':
    delete:
      responses:
        '200':
          description: OK
components:
  schemas:
    Foo:
      type: object
      properties: 
        property1: 
          type: object
    Bar:
      type: object
      properties:
        property1:
          type: array
          items:
            type: string
      allOf:
        - $ref: '#/components/schemas/Foo'

Swagger-Editor configuration options:

-

Describe the bug you're encountering

Related links in OpenAPI and JSON Schama validation specifications:

An instance validates successfully against this keyword if it validates successfully against all schemas defined by this keyword's value.

Seems there is an OpenAPI validation issue. Seems provided spec is invalid. Because Foo. property1 has an incompatible type (object) with Bar. property1 which one has type array. Swagger Editor does not find this validation issue and threat spec valid.

To reproduce...

Steps to reproduce the behavior:

  1. Go to https://editor.swagger.io
  2. Paste provided specification
  3. See no error

Expected behavior

If I got it correctly it impossible situation since the such schema is not able to validate at the same time against 2 different types (object, array).

Screenshots

Additional context or thoughts

Seems https://editor-next.swagger.io behavior is also incorrect.

char0n commented 1 year ago

Hi @mtovt,

Thanks for the report. I've rewritten your JSON Schema into single JSON Schema definition in Draft 5 (Draft 4 respectively):

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "$id": "http://json-schema.org/draft-04/schema#",
  "$ref": "#/$defs/Foo",
  "$defs": {
    "Foo": {
      "type": "object",
      "properties": {
        "property1": {
          "type": "object"
        }
      }
    },
    "Bar": {
      "type": "object",
      "properties": {
        "property1": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "allOf": [
        {
          "$ref": "#/$defs/Foo"
        }
      ]
    }
  }
}

This is completely valid JSON Schema and there is nothing invalid about it. It will be processed by tools like https://ajv.js.org/, https://www.jsonschemavalidator.net/ or https://extendsclass.com/json-schema-validator.html.

There is also a question of validating this JSON Schema agains the instance. It validates as well and it expects property1 to be an object.

Invalid

{
  "property1": []
}

Valid

{
  "property1": {}
}
mtovt commented 1 year ago

@char0n Thanks for your answer! It makes me partly clear. It seems, it really valid JSON schema. But what about OpenAPI?

Also, the following moments are unclear to me:

  1. ... It validates as well and it expects property1 to be an object.

If the expected type is object. Does it mean the Swagger editor is wrong in displaying [ > [...]]? Is this a bug?

  1. Also, I've tried to generate a Python client from the Generate Client button on the Swagger Editor site. It produces from the scheme above the following class with type list for property1.

    class Bar(Foo):
    ...
    swagger_types = {
        'property1': 'list[str]'
    }
  2. I'm still not sure if it is a valid OpenAPI even if it is valid over JSON Shema. OpenAPI says there is no multitype is possible. And I cannot find any extra information about it in the OpenAPI spec. Could you point out why this case is valid in OpenAPI?

OpenAPI v3.0.1 Schema Object says following

This object is an extended subset of the JSON Schema Specification Wright Draft 00.

properties - Property definitions MUST be a Schema Object and not a standard JSON Schema (inline or referenced).

The following properties are taken from the JSON Schema definition but their definitions were adjusted to the OpenAPI Specification.

  • type - Value MUST be a string. Multiple types via an array are not supported.

The OpenAPI Specification allows combining and extending model definitions using the allOf property of JSON Schema, in effect offering model composition. allOf takes an array of object definitions that are validated independently but together compose a single object.

As I understand it should independently validate. It seems it shall not pass validation against object and at the same time against array.

char0n commented 1 year ago

If the expected type is object. Does it mean the Swagger editor is wrong in displaying [ > [...]]? Is this a bug?

It is not a bug. This is the case of data inference from JSON Schema. SwaggerEditor/SwaggerUI tries to infer the data from JSON Schema as best as it can, and it decided that the list of string is the type of property1.

Also, I've tried to generate a Python client from the Generate Client button on the Swagger Editor site. It produces from the scheme above the following class with type list for property1.

This is the case of code generation. Code generation is provided via swagger-codegen java project. There is currently no specification around how to generate code from JSON Schema, nor is possible to generate code from all JSON Schema constructs. So the tooling does it's best to generate code that it considers to be the most usable.

I'm still not sure if it is a valid OpenAPI even if it is valid over JSON Shema. OpenAPI says there is no multitype is possible. And I cannot find any extra information about it in the OpenAPI spec. Could you point out why this case is valid in OpenAPI?

IMHO it is. There is nothing invalid I can see about it. The type is defined as string and allOf is used which is allowed. Here the validation concept is in play and I've demonstrated on ajv tool how the instance validates against your JSON Schema.


Overall, we have three independent contexts here in play:

For each of this context different tooling is used, and the tooling does it's best and decides how to interpret JSON Schema depending on the context. If you still have concerns, you should file an issue in https://github.com/OAI/OpenAPI-Specification/issues to get clarifications. But even if you get clarifications, it doesn't mean that tooling will accept the interpretation and adapt.

Here is also a proof that your OpenAPI definition validates succesfully against OpenAPI 3.0 metaschema: https://www.jsonschemavalidator.net/s/4cQMaEsJ