-
Notifications
You must be signed in to change notification settings - Fork 66
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
Non-string data keys #123
Comments
There's a little more info here: #122 (comment) |
Having similar problem, when key is Integer
Needed to revert back to version |
I am running into this as well. Would it make sense for a non-string key to simply raise a validation error? Something like this:
|
Hi pmusaraj, the schema allows me to define, that propertyName type is integer and I would expect this to work, not to raise an error. |
@legendetm hmm, as @davishmcclurg pointed out above, only string keys are valid JSON. |
When I read the core specification, it says the "name that the schema is testing will always be a string" what also may mean, that the key is stringified for testing. This does not say, that the key must be string.
But when viewing understanding object reference, then this states that object keys must always be strings.
In all, this can be confusing and you can find multiple examples in wild where the type for propertyNames is set to another type. It would be better, if the schema would be also considered invalid when non string type is specified. As currently the schema is considered valid, but cannot be validated against JSON. Considering the above, I will update my schema to use I checked how different online JSON schema validators validate, and this seems to be handled in multiple different ways:
|
@pmusaraj that's an interesting idea. I'm concerned about conflating schema validation errors and input errors, though. I think it makes sense to only yield errors for actual validation errors and not for bad input. Maybe it would be better to raise an error similar to
@legendetm I think the "key must be string" portion is implied because JSON schemas operate on JSON, which only allows string keys:
At the level the JSON schema specification operates on, there's no such thing as a non-string key.
That seems like the right approach 👍 |
Updating from This worked in it 'tests a schema' do
schema = JSONSchemer.schema(
{ title: 'A titled schema', additional_properties: false, type: 'object',
properties: { title: { type: 'string ' } } }.stringify_keys, insert_property_defaults: true
)
expect(schema).to be_valid({ title: 'some title' })
end While I think the new behaviour is understandable - I don't think this should have been a point change - it completely breaks the contract! I think it makes sense to have more clear errors (Although I do think there's certainly value in supporting symbol keys when it comes to ease of typing fixtures in Ruby). But ideally the library should avoid releasing point versions with breaking changes like this - this should definetely be added as a spec to make sure future changes can't break the behaviour. I'd be happy to contribute with a spec |
Thanks for the comment @myxoh! It seems like this is causing people enough pain to revert to the previous behavior. It's unfortunate because symbol keys are not well supported, ie it only works if both the schema and data use the same type of keys.
I agree it would be nice to support symbols properly. Though I'm not sure exactly what that looks like. I've been trying to avoid
That would be great. I believe the fix (if you don't mind contributing that as well) is to add a json_schemer/lib/json_schemer/schema/base.rb Line 625 in 0861dd2
|
This uses a refinement to support indifferent access for user-provided hashes. The interface is purposefully limited to prevent future use of hash methods that may not work as expected. Refinements are tricky, though, since you lose them whenever they're out of scope (eg, passing a hash to `include?` doesn't call the refinement's `==` method). I initially tried using activesupport's `HashWithIndifferentAccess` but it doesn't work for data hashes because `insert_property_defaults` needs to operate on the actual hash. Requiring all of activesupport just for `HashWithIndifferentAccess` also felt like a pain. The refinement works slightly different from `HashWithIndifferentAccess` because it leaves the keys as whatever type they already are. That might be a little confusing in error objects and `insert_property_defaults` but at least it's consistent with whatever is passed in. Symbol keys are mostly being tested by running the json-schema-test-suite tests again with symbol keys (using `symbolize_names: true` when parsing JSON). I also pulled those tests into their own file and cleaned things up. Addresses: - #91 - #123
This uses a refinement to support indifferent access for user-provided hashes. The interface is purposefully limited to prevent future use of hash methods that may not work as expected. Refinements are tricky, though, since you lose them whenever they're out of scope (eg, passing a hash to `include?` doesn't call the refinement's `==` method). I initially tried using activesupport's `HashWithIndifferentAccess` but it doesn't work for data hashes because `insert_property_defaults` needs to operate on the actual hash. Requiring all of activesupport just for `HashWithIndifferentAccess` also felt like a pain. The refinement works slightly different from `HashWithIndifferentAccess` because it leaves the keys as whatever type they already are. That might be a little confusing in error objects and `insert_property_defaults` but at least it's consistent with whatever is passed in. Symbol keys are mostly being tested by running the json-schema-test-suite tests again with symbol keys (using `symbolize_names: true` when parsing JSON). I also pulled those tests into their own file and cleaned things up. Addresses: - #91 - #123
This deep stringifies input hashes in order to support symbol (and other non-string) keys. Symbol keys have been a common issue for people forever (as evidenced by `InvalidSymbolKey`) and I've been hesitant to address it because duplicating hashes and stringifying keys hurts performance, but I think it's probably worth it. The tricky thing here is that `insert_property_defaults`, `before_property_validation`, and `after_property_validation` need access to the actual hashes instead of the stringified version. To work around that, the original instance is passed around in `Context` and can be accessed by location using `original_instance`. Values passed in hooks need to be re-stringified in case the user added non-string keys. If this becomes a performance bottleneck, it may make sense to add a way to turn it off for people that know they're using string keys. Related: - #91 - #123
This deep stringifies input hashes in order to support symbol (and other non-string) keys. Symbol keys have been a common issue for people forever (as evidenced by `InvalidSymbolKey`) and I've been hesitant to address it because duplicating hashes and stringifying keys hurts performance, but I think it's probably worth it. The tricky thing here is that `insert_property_defaults`, `before_property_validation`, and `after_property_validation` need access to the actual hashes instead of the stringified version. To work around that, the original instance is passed around in `Context` and can be accessed by location using `original_instance`. Values passed in hooks need to be re-stringified in case the user added non-string keys. If this becomes a performance bottleneck, it may make sense to add a way to turn it off for people that know they're using string keys. Related: - #91 - #123
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123
This deep stringifies input hashes in order to support symbol (and other non-string) keys. Symbol keys have been a common issue for people forever (as evidenced by `InvalidSymbolKey`) and I've been hesitant to address it because duplicating hashes and stringifying keys hurts performance, but I think it's probably worth it. The tricky thing here is that `insert_property_defaults`, `before_property_validation`, and `after_property_validation` need access to the actual hashes instead of the stringified version. To work around that, the original instance is passed around in `Context` and can be accessed by location using `original_instance`. Values passed in hooks need to be re-stringified in case the user added non-string keys. If this becomes a performance bottleneck, it may make sense to add a way to turn it off for people that know they're using string keys. Related: - #91 - #123
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys - Schema bundling See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123 - #136
This deep stringifies input hashes in order to support symbol (and other non-string) keys. Symbol keys have been a common issue for people forever (as evidenced by `InvalidSymbolKey`) and I've been hesitant to address it because duplicating hashes and stringifying keys hurts performance, but I think it's probably worth it. The tricky thing here is that `insert_property_defaults`, `before_property_validation`, and `after_property_validation` need access to the actual hashes instead of the stringified version. To work around that, the original instance is passed around in `Context` and can be accessed by location using `original_instance`. Values passed in hooks need to be re-stringified in case the user added non-string keys. If this becomes a performance bottleneck, it may make sense to add a way to turn it off for people that know they're using string keys. Related: - #91 - #123
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys - Schema bundling See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123 - #136
Released in 2.0.0. Data keys are deep-stringified to support symbols. Symbol values are not stringified. |
Non-string data keys cause errors when generating pointers:
Calling
to_s
inescape_json_pointer_token
solves the issue, but I'm not sure if it makes sense since non-string keys aren't JSON and can produce conflicts with other valid keys.For now, I'm opening this for discussion and to see if more people run into these errors.
Introduced: #122
The text was updated successfully, but these errors were encountered: