Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Having an id parameter in the schema messes up schema nesting #25

Open
c-lliope opened this issue Oct 30, 2015 · 9 comments
Open

Having an id parameter in the schema messes up schema nesting #25

c-lliope opened this issue Oct 30, 2015 · 9 comments

Comments

@c-lliope
Copy link
Contributor

I discovered this bug after generating schemas with prmd.

Minimal failing spec:

it 'works with an id' do
  response = double(body: '{ "a": "b" }')

  expect(response).to match_response_schema("top_level")
end

top_level.json

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "a": { "$ref": "nested.json" }
  }
}

nested.json

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "string",
  "id": "nested"
}

Removing the id from nested.json fixes the spec. Unfortunately, id is required for compatibility with prmd. Documentation

@seanpdoyle
Copy link
Collaborator

@Graysonwright thanks for uncovering this.

What was the test failure message?

@malandrina
Copy link

Looks like a PR for fixing an issue related to the supporting the id keyword was opened on json_schema a year ago: voxpupuli/json-schema#178

I am experimenting with using json_schema instead of json-schema in a branch. json_schema is what prmd and committee use and my guess is that our odds of achieving compatibility are higher if we use the same validator.

@c-lliope
Copy link
Contributor Author

Here's the error:

  1) Failing test case works with an id
     Failure/Error: expect(response).to match_response_schema("top_level")
             expected

             { "a": "b" }

             to match schema "top_level":

             {
         "$schema": "http://json-schema.org/draft-04/schema#",
         "type": "object",
         "properties": {
           "a": { "$ref": "nested.json" }
         }
       }


             ---

             The property '#/a' was not a valid schema in schema file:///Users/grayson/dev/tbot/reproduction/spec/support/schemas/top_level.json#
     # ./spec/failing_test_case.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:87:in `block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:86:in `block (2 levels) in <top (required)>'

malandrina pushed a commit that referenced this issue Nov 24, 2015
* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

  One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools.

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md
malandrina pushed a commit that referenced this issue Nov 24, 2015
* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

  One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools.

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  made an attempt at updating the specs.
malandrina pushed a commit that referenced this issue Nov 24, 2015
* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

  One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools.

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  made an attempt at updating the specs.
malandrina pushed a commit that referenced this issue Nov 24, 2015
* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

  One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This would
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  made an attempt at updating the specs.
@malandrina
Copy link

I was able to replace json-schema with json_schema with no problem but I haven't succeeded in updating the tests. Structuring the schemata in such a way that the JSON pointers are valid has been a struggle.

A good next step would be for @seanpdoyle to take a look at my branch and review Heroku's guidelines for structuring schemata to determine whether we actually want to take the approach of following their guidelines. If it is, we can take another stab at updating the specs.

@seanpdoyle
Copy link
Collaborator

@malandrina that all looks good!

What are the implications of switching gems?

Does the public API change?

Would consumers still be able to write somewhat arbitrary schemata, or would they be restricted to to writing schemata that conform to that standard?

Is our best approach an all-or-nothing change, or could/would/should we gradually migrate?

@malandrina
Copy link

@seanpdoyle great questions!

What are the implications of switching gems?

  • The public API would change: The strict option is not a thing in json_schema, so we would probably want to move away from supporting that option in the matcher.

  • Consumers would have to write schemata that conform to the Heroku conventions

  • I hadn’t thought much about the migration path but it’s an important question. The easiest approach for us would be an all-or-nothing change.

    Another idea which just occurred to me is to change the API of our matcher to support a heroku-http-api-toolchain option (only with a better name). That way people who aren’t using prmd, committee etc. and don’t care about compatibility can continue to use the matcher in its current state, while others who do need compatibility with Heroku’s tooling have a way to achieve it.

@malandrina
Copy link

Per our discussion IRL today, we've decided it makes sense to switch to json_schema.

Given that, we need to:

malandrina pushed a commit that referenced this issue Dec 18, 2015
The problem

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#add_schemata_to_document_store`.
seanpdoyle pushed a commit that referenced this issue Jan 26, 2018
The problem

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#add_schemata_to_document_store`.
seanpdoyle pushed a commit that referenced this issue Jan 26, 2018
The problem

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#add_schemata_to_document_store`.
seanpdoyle pushed a commit that referenced this issue Mar 2, 2018
The problem

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#add_schemata_to_document_store`.
@ms-ati
Copy link

ms-ati commented Mar 23, 2018

@malandrina @seanpdoyle Is this dead?

seanpdoyle pushed a commit that referenced this issue Apr 13, 2018
The problem

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#add_schemata_to_document_store`.
seanpdoyle pushed a commit that referenced this issue Apr 13, 2018
The problem

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#add_schemata_to_document_store`.
seanpdoyle pushed a commit that referenced this issue Apr 13, 2018
The problem

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#add_schemata_to_document_store`.
seanpdoyle pushed a commit that referenced this issue Apr 13, 2018
The problem:

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution:

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#build_and_populate_document_store`.
seanpdoyle pushed a commit that referenced this issue Apr 13, 2018
The problem:

* `json_matchers` cannot easily be used concurrently with Heroku's
  JSON API tools, i.e. `prmd` and `committee`, because `json_matchers`
  makes different assumptions about the structure of the user's
  schemata. An example of an incompatibility can be found in
  #25: `json_matchers`
  breaks when the `id` property is present within a schema, but the Heroku
  tools require the presence of the `id` property
  ([reference](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)).

  This is happening because the libraries used to dereference JSON
  pointers behave differently. `json-schema`, the library we're
  currently using, appears to conform less strictly to the JSON Schema
  specification than the library the Heroku tools use, `json_schema`.

The solution:

* One solution to this problem is to update `json_matchers` to use the
  same approach to validating schemata as the Heroku tools. This will
  require the following changes:

  1. Use `json_schema` instead of `json-schema` to validate schemata
  2. Update documentation to instruct readers to follow Heroku's
  guidelines for structuring schemata:
https://github.com/interagent/prmd/blob/master/docs/schemata.md

* In this commit I've replaced `json-schema` with `json_schema` and
  updated the schemata fixtures in the specs. Per [this json_schema
  issue](brandur/json_schema#22), in order to
  dereference JSON pointers referencing schemata in other files we need
  to access the gem's DocumentStore API directly. This is done in
  `Matcher#build_and_populate_document_store`.
@seanpdoyle
Copy link
Collaborator

Hey @Graysonwright and @malandrina from the past!

We were hoping for some clarification on this issue. Specifically, we were able
to reproduce this failing test case with the original validator, but we get
entirely different failures with the new validators.

With the old validator, when we specify the nested schema's id as
"nested.json" (instead of "nested"), the test passes:

it 'works with an id' do
  nested = create(:schema, name: "nested", json: {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "string",
    "id": "nested.json"
  })

  schema = create(:schema, {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
      "a": { "$ref": "nested.json" }
    }
  })

  response = double(body: '{ "a": "b" }')

  expect(response).to match_response_schema(schema)
end

That test passes with v0.8.0.

If you've experimented with the current master, renaming the nested
schema's { "id": "nested" } to { "id": "file:/nested.json" } and the
top-level schema's { "$ref": "nested.json" } to { "$ref": "file:/nested.json#" }, the tests pass:

it 'works with an id' do
  nested = create(:schema, name: "nested", json: {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "string",
    "id": "file:/nested.json"
  })

  schema = create(:schema, {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
      "a": { "$ref": "file:/nested.json#" }
    }
  })

  response = double(body: '{ "a": "b" }')

  expect(response).to match_response_schema(schema)
end

We are unclear on what the purpose of the nested id is, and why it needs to
correspond in whatever way to the top level reference.

Is there good documentation for this somewhere?

Do these workarounds make sense?

cc: @composerinteralia

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants