mikunn / openapi-schema-to-json-schema

Converts OpenAPI Schema Object to JSON Schema
75 stars 6 forks source link

Add support for `type` `file` #20

Open ehmicky opened 6 years ago

ehmicky commented 6 years ago

This is a continuation of #9

OpenAPI 2.0 has a type: "file" which describes part of a request/response with a multipart/form-data MIME type. OpenAPI 3.0 does not have that type anymore.

Details of how type file works The OpenAPI 2.0 specification is vague so I went through several GitHub issues/PRs of the specification to figure out the following:

Example 1

parameters:
- in: formData
  name: myContent
  type: object
  maxProperties: 1
- in: formData
  name: myOtherContent
  type: object
  maxProperties: 1

describes the following request body multipart/form-data; boundary=%%%:

%%%
Content-Disposition: form-data; name="myContent"
{ "hello": "world" }
%%%
Content-Disposition: form-data; name="myOtherContent"
{ "world": "hello" }
%%%--

Example 2

parameters:
- in: formData
  name: myContent
  type: file
  maxProperties: 1

describes the following request body multipart/form-data; boundary=%%%:

%%%
Content-Disposition: form-data; name="myContent"; filename="..."
{ "hello": "world" }
%%%--

Example 3

responses:
  200:
    schema:
      type: file
      maxProperties: 1

could describe the following response body multipart/form-data; boundary=%%%:

%%%
Content-Disposition: form-data; name="myContent"; filename="..."
{ "hello": "world" }
%%%
Content-Disposition: form-data; name="myOtherContent"; filename="..."
{ "world": "hello" }
%%%--

In that example, it is unspecified whether the schema target myContent or myOtherContent.

Does type file makes sense with JSON schemas?

I think the type file does not imply anything about the content being JSON or not JSON.

The content of a request body or response body could be JSON. It could also be treated as a string where we want to validate the maxLength or pattern.

On the other hand, a formData or body request parameter or a response body with type string or with no type can be non-JSON.

Whether the content is JSON compatible depends on the MIME types, which are described by consumes and produces (OpenAPI 2.0) or the Accept and Content-Type request headers (OpenAPI 3.0). Even then a non-JSON compatible request body or response body might be parsed to a JSON compatible value.

So I think the content of a request body or response body with type file might still be described by a JSON schema.

Purpose of supporting "type": "file"

It seems to me that OpenAPI 2.0. created the "type": "file" solely to specify whether the filename property is present or not. Overloading the JSON schema type was probably a bad decision that they reverted in OpenAPI 3.0. However users might still want to use the other JSON schema properties to validate the targeted part of the request body or response body. In the example above users might still want to validate the file content against the maxProperties constraint.

The following proposals would allow users to re-use those JSON schemas as opposed to the current behavior of throwing when encountering that type.

Solution 1

Removing the type property.

Solution 2

Guessing the type property from the sibling properties. E.g. { "type": "file", "minProperties": 1, "minLength": 1 } would become { "type": ["object", "string"], "minProperties": 1, "minLength": 1 }. If the type cannot be guessed, it is removed.

I can submit a PR if needed.