apiaryio / api-blueprint

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

JSON Schema for array of objects is Invalid #338

Closed kesslerdev closed 5 years ago

kesslerdev commented 8 years ago

Hello i have a problem when i validate an array of objects due of brackets in items properties

exemple: for invalid data : (unwanted properties in object & empty objects)

{
  "links": [
    {
      "reld": "invalid-data",
      "rel": "self",
      "href": "http://crm.loctest/api/v1/companies.json?max_per_page=1&page=1&expand%5B0%5D=persons"
    },
    {
      "rel": "next",
      "href": "http://crm.loctest/api/v1/companies.json?max_per_page=1&page=2&expand%5B0%5D=persons"
    },
    {
      "rel": "last",
      "href": "http://crm.loctest/api/v1/companies.json?max_per_page=1&page=2&expand%5B0%5D=persons",
      "reld": "invalid-data"
    },
    {}
  ]
}

For structures

# Data Structures

## Link (object)
+ rel: *self* (string, required)
+ href: *an_url* (string, required)

## List
+ links (array[Link],fixed,required)

it prduce this schema :

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "links": {
      "type": "array",
      "items": [
        {
          "type": "object",
          "properties": {
            "rel": {
              "type": "string"
            },
            "href": {
              "type": "string"
            }
          },
          "required": [
            "rel",
            "href"
          ],
          "additionalProperties": false
        }
      ]
    }

  },
  "required": [
    "links"
  ]
}

in this case the validator show errors only in the first element others dont validate. In other issue ( #328 ) i show it is the normal behavior, item is an array of possible types but in drafter-04 for this it could be use the oneOf property. The schema must be rewriten to :

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "links": {
      "type": "array",
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "rel": {
                "type": "string"
              },
              "href": {
                "type": "string"
              }
            },
            "required": [
              "rel",
              "href"
            ],
            "additionalProperties": false
          }
        ]
      }
    }
  },
  "required": [
    "links"
  ]
}
pksunkara commented 8 years ago

I am afraid I can't understand your question. The generated Schema looks correct to me. But you want the schema to be generated to something else?

kesslerdev commented 8 years ago

yes with this generation the schema don't validate all of objects in my array but only the first one. Or anthoter syntax (in blueprint) exist for validate all items of an array ?

kylef commented 8 years ago

@kesslerdev The generated schema appears to work as expected, here's examples I've tested. Could you please elaborate on what the problem you are facing is? Perhaps with actual JSON examples.

Schema

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "links": {
      "type": "array",
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "rel": {
                "type": "string"
              },
              "href": {
                "type": "string"
              }
            },
            "required": [
              "rel",
              "href"
            ],
            "additionalProperties": false
          }
        ]
      }
    }
  },
  "required": [
    "links"
  ]
}

Validates Successfully

{
  "links": [
    {
        "rel": "x",
        "href": "x"
    },
    {
        "rel": "x",
        "href": "x"
    },
    {
        "rel": "x",
        "href": "x"
    }
  ]
}

Fails Validation

Errors:

{
  "links": [
    {
        "rel": "x",
        "href": "x"
    },
    {
        "rel": "x",
        "href": "x"
    },
    {
        "href": "x"
    }
  ]
}
kylef commented 8 years ago

And I want to point out, your example also fails as expected with the schema.

kesslerdev commented 8 years ago

you schema is correct but when i use MSON for generating the schema, it look wrong : it generate an array of object in items property instead of just an object or the oneOf format. In this case the generated schema validate only the first element of my array.

kylef commented 8 years ago

@kesslerdev In my comment I used the generated schema. The generated schema does validate every item in the array. Perhaps you're experiencing a bug in a JSON validation library instead?

kesslerdev commented 8 years ago

@kylef what is the MSON code used for generting your schema ? i think my MSON is incorrect.

kylef commented 8 years ago

@kesslerdev, I'm was using the schema from your comment, the "generated" one.