OpenAPI.NET icon indicating copy to clipboard operation
OpenAPI.NET copied to clipboard

Round tripping a V2 document is generating an invalid V2 document

Open Shwetap05 opened this issue 7 years ago • 4 comments

  1. Read below Valid V2 document into OpenAPIDocument using OpenApiStringReader().Read()
  2. Serialize the document from above step into V2 using SerializeAsJson( OpenApiSpecVersion.OpenApi2_0 )
  3. This converts a valid V2 document into invalid document, notice the in:body paramter is converted into in:formData

Valid Document Provided as input in step 1)

{
  "swagger": "2.0",
  "info": {
    "version": "v1",
    "title": "NotificationsSite"
  },
  "host": "test",
  "schemes": [ "https" ],
  "paths": {
    "/api/{aadClientId}/emails": {
      "post": {
        "tags": [ "Emails" ],
        "operationId": "Emails_Post",
        "consumes": [ "application/json", "text/json", "application/xml", "text/xml", "application/x-www-form-urlencoded" ],
        "produces": [ "application/json", "text/json", "application/xml", "text/xml" ],
        "parameters": [
          {
            "name": "aadClientId",
            "in": "path",
            "required": true,
            "type": "string",
            "format": "uuid"
          },
          {
            "name": "value",
            "in": "body",
            "required": true,
            "schema": { "$ref": "#/definitions/Email" }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "type": "object" }
          }
        }
      }
    }
  },
  "definitions": {
    "Email": {
      "required": [ "Subject", "Recipients" ],
      "type": "object",
      "properties": {
        "Subject": { "type": "string" },
        "Recipients": {
          "type": "array",
          "items": { "$ref": "#/definitions/Recipient" }
        },
        "HtmlBody": { "type": "string" },
        "Tokens": {
          "type": "array",
          "items": { "$ref": "#/definitions/TemplateToken" }
        },
        "TemplateName": { "type": "string" },
        "Importance": {
          "format": "int32",
          "type": "integer"
        },
        "ReplyToAlias": { "type": "string" },
        "From": { "type": "string" },
        "IsTracked": { "type": "boolean" },
        "IsPreview": { "type": "boolean" },
        "EmailType": { "type": "string" }
      }
    },
    "Recipient": {
      "type": "object",
      "properties": {
        "Alias": { "type": "string" },
        "SendType": {
          "format": "int32",
          "type": "integer"
        }
      }
    },
    "TemplateToken": {
      "type": "object",
      "properties": {
        "Id": { "type": "string" },
        "Value": { "type": "string" }
      }
    }
  }
}

Invalid document generated in step 3)

{
  "swagger": "2.0",
  "info": {
    "title": "NotificationsSite",
    "version": "v1"
  },
  "host": "test",
  "basePath": "/",
  "schemes": [
    "https"
  ],
  "paths": {
    "/api/{aadClientId}/emails": {
      "post": {
        "tags": [
          "Emails"
        ],
        "operationId": "Emails_Post",
        "consumes": [
          "application/json",
          "text/json",
          "application/xml",
          "text/xml",
          "application/x-www-form-urlencoded"
        ],
        "produces": [
          "application/json",
          "text/json",
          "application/xml",
          "text/xml"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "aadClientId",
            "required": true,
            "type": "string",
            "format": "uuid"
          },
          {
            "in": "formData",
            "name": "Subject",
            "required": true,
            "type": "string"
          },
          {
            "in": "formData",
            "name": "Recipients",
            "required": true,
            "type": "array",
            "items": {
              "$ref": "#/definitions/Recipient"
            }
          },
          {
            "in": "formData",
            "name": "HtmlBody",
            "type": "string"
          },
          {
            "in": "formData",
            "name": "Tokens",
            "type": "array",
            "items": {
              "$ref": "#/definitions/TemplateToken"
            }
          },
          {
            "in": "formData",
            "name": "TemplateName",
            "type": "string"
          },
          {
            "in": "formData",
            "name": "Importance",
            "type": "integer",
            "format": "int32"
          },
          {
            "in": "formData",
            "name": "ReplyToAlias",
            "type": "string"
          },
          {
            "in": "formData",
            "name": "From",
            "type": "string"
          },
          {
            "in": "formData",
            "name": "IsTracked",
            "type": "boolean"
          },
          {
            "in": "formData",
            "name": "IsPreview",
            "type": "boolean"
          },
          {
            "in": "formData",
            "name": "EmailType",
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "type": "object"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "Email": {
      "required": [
        "Subject",
        "Recipients"
      ],
      "type": "object",
      "properties": {
        "Subject": {
          "type": "string"
        },
        "Recipients": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Recipient"
          }
        },
        "HtmlBody": {
          "type": "string"
        },
        "Tokens": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/TemplateToken"
          }
        },
        "TemplateName": {
          "type": "string"
        },
        "Importance": {
          "format": "int32",
          "type": "integer"
        },
        "ReplyToAlias": {
          "type": "string"
        },
        "From": {
          "type": "string"
        },
        "IsTracked": {
          "type": "boolean"
        },
        "IsPreview": {
          "type": "boolean"
        },
        "EmailType": {
          "type": "string"
        }
      }
    },
    "Recipient": {
      "type": "object",
      "properties": {
        "Alias": {
          "type": "string"
        },
        "SendType": {
          "format": "int32",
          "type": "integer"
        }
      }
    },
    "TemplateToken": {
      "type": "object",
      "properties": {
        "Id": {
          "type": "string"
        },
        "Value": {
          "type": "string"
        }
      }
    }
  }
}

Shwetap05 avatar May 16 '18 18:05 Shwetap05

@Shwetap05 What's the priority on this bug? I'd like to get a 1.0.1 patch release out because I need the other fixes I don't in a release package. Do you want this fix in 1.0.1? Have you started looking at it? Do you want me to take a look at fixing it?

darrelmiller avatar May 18 '18 18:05 darrelmiller

@darrelmiller Its not a high priority bug, could be a P3, doesn't need to be fixed in 1.0.1. I have not started looking as do not have bandwidth to look into for next two weeks. So i think we can leave it open for now.

Shwetap05 avatar May 18 '18 20:05 Shwetap05

@Shwetap05 Cool. I'll take a quick look and see if it's an easy fix. If it is I'll try and get it into 1.0.1

darrelmiller avatar May 18 '18 21:05 darrelmiller

@Shwetap05 So.... there is probably no easy answer to this. The original V2 document is arguably invalid. By declaring both application/json and application/x-www-form-urlencoded for the consumes property it becomes challenging describe this API in V2. V2 requires using formData parameters for declaring form bodies, but if you are passing JSON then you wouldn't use the form body. I'm not aware of a way of supporting both in V2.

Interestingly, the V3 document that we produce is actually valid.

darrelmiller avatar May 20 '18 23:05 darrelmiller