voxpupuli / json-schema

Ruby JSON Schema Validator
MIT License
1.54k stars 243 forks source link

Confusion about `allOf` usage, failed validation #279

Open thewatts opened 8 years ago

thewatts commented 8 years ago

Gem Version: 2.5.2

My current schema is failing validation on strict mode while using allOf to combine schemas. I've looked at the wiki, read blog posts, searched for issues, stack overflow, etc - still no dice.

Validation passes when using all the items written out:

{
  "type":"object",
  "required":[
    "id",
    "email",
    "first_name",
    "last_name",
    "phone",
    "avatar",
    "campus",
    "token"
  ],
  "properties": {
    "id": { "type": "fixnum" },
    "email": { "type": "string" },
    "first_name": { "type": "string" },
    "last_name": { "type": "string" },
    "phone": { "type": ["string", "null"] },
    "avatar": { "$ref": "avatar.json" },
    "campus": { "$ref": "campus.json" },
    "token": { "type": "string" },
  }
}

But when I use allOf to combine schemas, I get this error:

JSON::Schema::ValidationError:
       The property '#/' of type Hash did not match all of the required schemas

Here's my schema:

{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "allOf": [
    { "$ref": "user.json" },
    {
      "type": "object",
      "required": [
        "token"
      ],
      "properties": {
        "token": {
          "type": "string"
        }
      }
    }
  ]
}

Am I missing something? :sweat_smile:

RST-J commented 8 years ago

Could you please provide an example of data which should validate but does not?

thewatts commented 8 years ago

@RST-J Sorry for the delay! Must have missed the notification.

Here's an example:

{
  "id": 1,
  "email": "john.doe@example.com",
  "first_name": "John",
  "last_name": "Doe",
  "phone": "555-555-5555",
  "avatar": {
    "thumbnail_url": "http://google.com",
    "medium_url": "http://google.com",
    "original_url": "http://google.com"
  },
  "campus": {
    "id": 1,
    "name": "Smallville"
  },
  "token": "abc123def456"
}
RST-J commented 8 years ago

I just realized that I still need more details to reproduce that, namely the schemas defined in avatar.json, campus.json and user.json. Can you also provide these?

thewatts commented 8 years ago

Sure thing @RST-J! Thanks for your quick reply!

// user.json
{
  "type":"object",
  "required":[
    "id",
    "email",
    "first_name",
    "last_name",
    "phone",
    "avatar",
    "campus"
  ],
  "properties": {
    "id": { "type": "fixnum" },
    "email": { "type": "string" },
    "first_name": { "type": "string" },
    "last_name": { "type": "string" },
    "phone": { "type": ["string", "null"] },
    "avatar": { "$ref": "avatar.json" },
    "campus": { "$ref": "campus.json" }
  }
}
// avatar.json
{
  "type":"object",
  "required":[
    "thumbnail_url",
    "medium_url",
    "original_url"
  ],
  "properties": {
    "thumbnail_url": { "type": "string" },
    "medium_url": { "type": "string" },
    "original_url": { "type": "string" }
  }
}
// campus.json
{
  "type":"object",
  "required":[
    "id",
    "name"
  ],
  "properties": {
    "id": { "type": "fixnum" },
    "name": { "type": "string" }
  }
}
bopm commented 7 years ago

@thewatts why does this issue closed? It's still failing with presented test data in every version including the latest. Is there something wrong with how we use allOf?

glaucocustodio commented 7 years ago

allOf seems not to be working.. Can you reopen this issue please @RST-J @iainbeeston?

iainbeeston commented 7 years ago

@thewatts can you please confirm if this works with the latest version of the gem? (The most recent release fixed some bugs)

glaucocustodio commented 7 years ago

I tested against 2.7.0 and it didn't work.

iainbeeston commented 7 years ago

Thanks, I'll take a look when I can find some time

acaloiaro commented 7 years ago

@thewatts This is actually the expected behavior of v4; albeit a behavior that few people like. What you were trying to define is an inheritance relationship which – as of json-schema v4 – is not possible. This will likely be addressed in json-schema v5.

Workaround in the mean time: 1. Add "additionalProperties": true to user.json and define your token property as follows:

    {
      "type": "object",
      "properties": { "token": { "type": "string" } },
    }

Or even more simply:

{
   "token": {"type": "string"}
}