Hilzu / express-openapi-validate

Express middleware to validate requests based on an OpenAPI 3 document
Apache License 2.0
75 stars 12 forks source link

Improve SchemaObject interface by allowing ReferenceObject in some properties #76

Open joelposti opened 2 years ago

joelposti commented 2 years ago

Improved SchemaObject interface. Many of its properties can be of type ReferenceObject per OpenAPI specification.

Issue

Currently OpenAPI document that makes use of $ref in SchemaObjects do not pass TypeScript type checking because SchemaObject does not allow ReferenceObjects although the OpenAPI specification allows them. The following valid use cases of ReferenceObject do not pass type checking.

import {
  SchemaObject,
} from 'express-openapi-validate/dist/OpenApiDocument'

const refInOneOf: SchemaObject = {
  oneOf: [
    {
      $ref: '#/components/schemas/FooBar'
    }
  ]
}

const refInNot: SchemaObject = {
  not: {
    $ref: '#/components/schemas/FooBar'
  }
}

const refInItems: SchemaObject = {
  type: 'array',
  items: {
    $ref: '#/components/schemas/FooBar'
  }
}

const refInAdditionalProperties: SchemaObject = {
  additionalProperties: {
    $ref: '#/components/schemas/FooBar'
  }
}

const refInProperty: SchemaObject = {
  type: 'object',
  properties: {
    fooBar: {
      $ref: '#/components/schemas/FooBar'
    }
  }
}

Argument for the changes in this PR

The use cases demonstrated above should be valid according to OpenAPI specification at https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schema-object and should thus pass type checking.

allOf - Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. oneOf - Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. anyOf - Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. not - Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. items MUST be present if the type is array. properties - Property definitions MUST be a Schema Object and not a standard JSON Schema (inline or referenced). additionalProperties - Value can be boolean or object. Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. Consistent with JSON Schema, additionalProperties defaults to true.

Explanation on the part of properties leaves open the question whether individual properties can be ReferenceObjects. But I think they can because there is an example of such usage in the same specification document https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#simple-model.

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "address": {
      "$ref": "#/components/schemas/Address"
    },
    "age": {
      "type": "integer",
      "format": "int32",
      "minimum": 0
    }
  }
}
joelposti commented 2 years ago

It seems tests do not pass after making these changes. I will fix the issue.

joelposti commented 2 years ago

I fixed the issue. Tests pass now.

joelposti commented 2 years ago

Hei @Hilzu! Could you take a look at this pull request? I would like to have this issue fixed here in the upstream.