apiaryio / api-blueprint

API Blueprint
https://apiblueprint.org
MIT License
8.63k stars 2.14k forks source link

One Of and JSON schema rendering #392

Closed mleace closed 7 years ago

mleace commented 7 years ago

Hello,

I have one issue with JSON schema rendered from MSON. I have these objects in MSON:

## CELAdditionalInfo (object)
+ tenor: 10 (number, optional) - number of installment of contract when signed
+ firstInstallmentDueDate: 2017-02-27 (string, required) -  due date of this contract

## RELAdditionalInfo (object)
+ creditLimit (number, required) - credit limit amount of an account   
+ billingDate: 2017-10-05 (string, optional) - date generated when contract is signed

## Contract (object)
+ contractNumber: 12345678za (string, required) - ID of a contract
+ approvedAt: 2016-01-20 (string, optional) - date when contract was created
+ contractType: CEL (enum, required) - contract type
    + CEL - Close End Loan
    + REL - Revolving Loan
+ One Of
    + celInfo (CELAdditionalInfo,required) - additional info of CEL only
    + relInfo (RELAdditionalInfo,required) - additional info of REL only

The idea behind it is that we have two type of contracts, each having some common properties but also some additional, specific to the type of contract.

Rendered JSON schema seems OK, until I run Dredd tests (or any other JSON-schema validation, such as this against responses from my API. Validation shows error:

Data is valid against more than one schema from "oneOf": indices 0 and 1

Trouble is in rendered JSON schema. Schema from Apiary is (just relevant part):

"oneOf": [
    {
      "properties": {
        "celInfo": {
          "type": "object",
          "properties": {
            "tenor": {
              "type": "number",
              "description": "number of installment of contract when signed"
            },
            "firstInstallmentDueDate": {
              "type": "string",
              "description": "due date of this contract, in case client has more than 1 contract, it should be the merged due date of client"
            }
          },
          "required": [
            "firstInstallmentDueDate",
          ],
          "description": "additional info of CEL only"
        }
      }
    },
    {
      "properties": {
        "relInfo": {
          "type": "object",
          "properties": {
            "creditLimit": {
              "type": "number",
              "description": "credit limit amount of an account"
            },
            "billingDate": {
              "type": "string",
              "description": "date generated when contract is signed"
            },
          "required": [
            "creditLimit"
          ],
          "description": "additional info of REL only"
        }
      }
    }
  ]

Once I manually add relInfo and celInfo as required to the schema (see below - actually this is the output I would expect from MSON above), validation is OK.

"oneOf": [
    {
      "properties": {
        "celInfo": {
          "type": "object",
          "properties": {
            "tenor": {
              "type": "number",
              "description": "number of installment of contract when signed"
            },
            "firstInstallmentDueDate": {
              "type": "string",
              "description": "due date of this contract, in case client has more than 1 contract, it should be the merged due date of client"
            }
          },
          "required": [
            "firstInstallmentDueDate",
          ],
          "description": "additional info of CEL only"
        }
      }, "required": ["celInfo"]
    },
    {
      "properties": {
        "relInfo": {
          "type": "object",
          "properties": {
            "creditLimit": {
              "type": "number",
              "description": "credit limit amount of an account"
            },
            "billingDate": {
              "type": "string",
              "description": "date generated when contract is signed"
            },
          "required": [
            "creditLimit"
          ],
          "description": "additional info of REL only"
        }
      }, "required": ["relInfo"]
    }
  ]

Is there a way how to get these "required" generated for me, or perhaps another way how to achieve correct JSON schema validation? Thank you in advance.

pksunkara commented 7 years ago

This has been fixed apiaryio/drafter#453 and we are working on deploying this as soon as we can.