Skip to content

fix: support true/false JSON Schemas#311

Merged
magicmatatjahu merged 8 commits into
asyncapi:masterfrom
magicmatatjahu:true-false-schemas
Jun 16, 2021
Merged

fix: support true/false JSON Schemas#311
magicmatatjahu merged 8 commits into
asyncapi:masterfrom
magicmatatjahu:true-false-schemas

Conversation

@magicmatatjahu

@magicmatatjahu magicmatatjahu commented Jun 2, 2021

Copy link
Copy Markdown
Member

Description

As in title. As we support JSON Schema draft-07 as schema, then we should also support true/false schemas in JSON Schema of our spec and of course in parser. More info #232

Related issue(s)
Fixes #232

@magicmatatjahu magicmatatjahu added the bug Something isn't working label Jun 2, 2021
Comment thread lib/models/schema.js Outdated
Comment on lines +20 to +24
constructor (json) {
const isBoolSchema = typeof json === 'boolean';
super(isBoolSchema ? {} : json);
this.isBoolSchema = isBoolSchema;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the biggest problem here, how to handle it, because we don't support true/false schema from the beginning. This solution both adds boolean schema support, and is also backward compatible. Another solution is to return the schema as boolean, but then we must adjust a lot of functions in another models, which returns array of schemas or single schema. Any thoughts?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to keep all schemas as Schema object types. Also, if you return pure boolean types here, checks would need always to be performed as a strict comparison (=== / !===), which sounds pretty error-prone. schema.isBoolSchema sounds like a more readable version and also less error-prone since we can make a statement on "all schemas are represented as Schema objects.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yea it is a tricky problem.

In theory, I would never expect an instance of the Schema to be returned to me if the schema was a boolean. Especially since in all other aspects, the parser structure follows the exact type dictated by the specification.

However, I can see the benefits of having this isBoolSchema function 🧐 Not sure what the appropriate approach is here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About backward compatible I thought wrong, We didn't support the true/false schemas in parser, because if someone wrote them then had the errors from ajv, because we had broken JSON Schema for spec. I can change the current behaviour and return the boolean in places where we operate on Schema model, but... handling boolean schemas as class is probably less error-prone in templates as @smoya wrote, because then we haven't to check in every place that schema is bool or not. I can only imagine the pain.

Also in current changes I passed for true schema the {} model body and for false the { not: {} } and by this we have two ways for handling Boolean Schemas.

@jonaslagoni jonaslagoni Jun 16, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep true, I can see it as a benefit as well in terms of the boolean functions I guess 👍

Comment on lines -50 to -61
{
title: '/channels/mychannel/publish/message/payload/additionalProperties should be object',
location: {
jsonPointer: '/channels/mychannel/publish/message/payload/additionalProperties',
startLine: 13,
startColumn: 38,
startOffset: offset(252, 13),
endLine: 15,
endColumn: 15,
endOffset: offset(297, 15)
}
},

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we will merge it asyncapi/spec-json-schemas#63 then this error won't be throw.

@magicmatatjahu magicmatatjahu requested review from derberg and smoya June 16, 2021 10:29

@jonaslagoni jonaslagoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few things to discuss.

Comment thread lib/models/schema.js Outdated
Comment thread test/asyncapiSchemaFormatParser_test.js

@jonaslagoni jonaslagoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner 👍 Still got a small comment.

Comment thread lib/models/schema.js Outdated
Comment on lines +21 to +22
super(json === false ? {} : json);
this._json = json;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it not be possible to change the base check to check for undefined instead of booleans as well?🤔 Or would that create problems? 🤔

Setting _json twice seems like the wrong approach 😅

@magicmatatjahu magicmatatjahu Jun 16, 2021

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base ctor has:

    if (!json) throw new ParserError(`Invalid JSON to instantiate the ${this.constructor.name} object.`);
    this._json = json;

I don't want to change it, because handling false schemas in base class isn't a good idea. At the moment it's only needed for Schema so I pass empty object as workaround

Setting _json twice seems like the wrong approach 😅

Yep, but it's still "fine" if we make this assignment in child ctor, not in other place :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also checking undefined is not good idea - JSON Schema hasn't undefined type/value

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my understanding, the base class constructor check, in theory, should only make sure that the received value is not undefined/null 🤔

Therefore you could change that referenced line from a lazy check to strict:

    if (json === undefined || json === null) throw new ParserError(`Invalid JSON to instantiate the ${this.constructor.name} object.`);

That way you can remove this._json = json; in this constructor.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't see the cases where the argument would be 0, NaN, false, ""

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps I'm sitting in work too long today 😅 Thanks! Changed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha 😆 That or I have, lets see if others find a problem with this approach 😆

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but even if you put "" or 0 what it's a value in spec? Can we pass something like this in spec itself? Only false has some "value", but only related to Schema object.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I know of no, hence my suggestion.

The only dilemma I can see could be if the JSON Schema for the specification allowed such values where objects are expected, then it would no longer throw a parser error here. I just don't see the use-case 🤷

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also 😅

jonaslagoni
jonaslagoni previously approved these changes Jun 16, 2021

@jonaslagoni jonaslagoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why you have updated dist/bundle.js?

Other than that it looks good from my perspective 🙂

@magicmatatjahu

Copy link
Copy Markdown
Member Author

@jonaslagoni Probably when I run the integration tests I didn't check the changes for dist... but it has change on every release :) Could you approve again?

@jonaslagoni jonaslagoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still detects bundle changes 🙂

Comment thread types.d.ts

@jonaslagoni jonaslagoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last change I think 😆

Comment thread test/asyncapiSchemaFormatParser_test.js Outdated
@sonarqubecloud

Copy link
Copy Markdown

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

No Coverage information No Coverage information
0.0% 0.0% Duplication

@jonaslagoni jonaslagoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can accept that code smell as we already have a similar one and I dont see any other way of shorting that check 👍

@magicmatatjahu magicmatatjahu merged commit 5cc631b into asyncapi:master Jun 16, 2021
@magicmatatjahu magicmatatjahu deleted the true-false-schemas branch June 16, 2021 16:01
@magicmatatjahu

Copy link
Copy Markdown
Member Author

@jonaslagoni Thanks!

@asyncapi-bot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.5.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handling schema true and false

4 participants