json-schema icon indicating copy to clipboard operation
json-schema copied to clipboard

Error while validating JSON-schema fragments that have $refs outside of the fragment

Open tdooner opened this issue 10 years ago • 4 comments

Hey, I'm trying to do something which I haven't seen any json-schema implementation handle well yet -- validating a sub-schema that has references outside of itself. This seems common when using JSON Hyper-Schema.

I was expecting this to work:

schema = JSON.parse(<<-SCHEMA)
{
  "$schema": "http://json-schema.org/draft-04/hyper-schema",
  "definitions": {
    "foo": {
      "type": ["integer"]
    },
    "bar": {
      "links": [
        {
          "method": "POST",
          "href": "/url",
          "title": "search",
          "rel": "matches",
          "schema": {
            "properties": {
              "foo": {
                "$ref": "#/definitions/foo"
              }
            },
            "type": [
              "object"
            ],
            "required": [
              "foo"
            ]
          }
        }
      ]
    }
  }
}
SCHEMA

puts 'valid' if JSON::Validator.validate!(schema, { foo: 1234 }, fragment: '#/definitions/bar/links/0/schema')

..but instead I get:

/home/tom/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/json-schema-2.5.0/lib/json-schema/validator.rb:115:in `validate': undefined method `validate' for #<Hash:0x007facc17ca928> (NoMethodError)
        from /home/tom/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/json-schema-2.5.0/lib/json-schema/validator.rb:263:in `validate!'
        from repro.rb:52:in `<main>'

Calling #initialize_schema on @base_schema looks like it will work, but then if I try to actually validate the document, I get the error I'm expecting JSON::Schema::SchemaError: The fragment '/definitions' does not exist on schema 00022aeb-886b-5dfe-aef9-7cfafc4e2002# because of how @base_schema is mutated to be only the fragment.

I see this as a change that could be implemented without breaking backwards compatibility. I'm happy to work on a PR for this, but wanted to double-check before working on something.

tdooner avatar Feb 09 '15 01:02 tdooner

by all means, this would be great - hyper schema support is something this library is currently lacking.

On Feb 8, 2015, at 5:21 PM, Tom Dooner [email protected] wrote:

Hey, I'm trying to do something which I haven't seen any json-schema implementation handle well yet -- validating a sub-schema that has references outside of itself. This seems common when using JSON Hyper-Schema.

I was expecting this to work:

schema = JSON.parse(<<-SCHEMA) { "$schema": "http://json-schema.org/draft-04/hyper-schema", "definitions": { "foo": { "type": ["integer"] }, "bar": { "links": [ { "method": "POST", "href": "/url", "title": "search", "rel": "matches", "schema": { "properties": { "foo": { "$ref": "#/definitions/foo" } }, "type": [ "object" ], "required": [ "foo" ] } } ] } } } SCHEMA

puts 'valid' if JSON::Validator.validate!(schema, { foo: 1234 }, fragment: '#/definitions/bar/links/0/schema') ..but instead I get:

/home/tom/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/json-schema-2.5.0/lib/json-schema/validator.rb:115:in validate': undefined methodvalidate' for #Hash:0x007facc17ca928 (NoMethodError) from /home/tom/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/json-schema-2.5.0/lib/json-schema/validator.rb:263:in validate!' from repro.rb:52:in

' Calling #initialize_schema on @base_schema looks like it will work, but then if I try to actually validate the document, I get the error I'm expecting JSON::Schema::SchemaError: The fragment '/definitions' does not exist on schema 00022aeb-886b-5dfe-aef9-7cfafc4e2002# because of how @base_schema is mutated to be only the fragment.

I see this as a change that could be implemented without breaking backwards compatibility. I'm happy to work on a PR for this, but wanted to double-check before working on something.

— Reply to this email directly or view it on GitHub.

hoxworth avatar Feb 09 '15 03:02 hoxworth

@hoxworth I hate to be that github contributor, but could I ask you for some help in how to begin approaching this? It looks like the notion of a current_schema is pretty sewn throughout the entire gem.

My first instinct is that we should maintain some kind of pointer to what the "#/" ref refers to, and use that instead of current_schema here. But a really naive implementation of that that I cooked up locally caused a bunch of test failures.

Shall I continue down this path or can you think of a different implementation that makes sense?

tdooner avatar Feb 10 '15 06:02 tdooner

I'm afraid it's hard to judge without seeing the code. Even test failures are not necessarily a bad thing (they could be bogus tests, although I'd be doubtful at first). Could you push up a WIP pull request so we can see?

Also, I can't help thinking that #186 might help this (might not be true)

iainbeeston avatar Feb 10 '15 08:02 iainbeeston

Not totally sure this is correct, but I think I ran into this while trying to validate a document against this schema: https://api.pmp.io/schemas/image

Any movement on this?

will-in-wi avatar May 21 '15 19:05 will-in-wi