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

Support multiple property names in discriminator keyword #1663

Open
pkuczynski opened this issue Jun 28, 2021 · 11 comments
Open

Support multiple property names in discriminator keyword #1663

pkuczynski opened this issue Jun 28, 2021 · 11 comments

Comments

@pkuczynski
Copy link

pkuczynski commented Jun 28, 2021

What version of Ajv you are you using?

8.6

What problem do you want to solve?

My schema depends on value of two fields, so I wanted to implement something like this:

{
    type: 'object',
    discriminator: { propertyName: ['a', 'b'] }
    required: ['a', 'b'],
    oneOf: [
       {
          properties: {
            a: { const: true }
            b: { const: 'b' }
            c: { type: 'string' }
          }
       },
       {
          properties: {
            a: { const: false }
            b: { const: 'bb' }
            c: { type: 'number' }
          }
       }
       ...
    ]
}

What do you think is the correct solution to problem?

Add ability to define multiple properties in discriminator

Will you be able to implement it?

I am not sure...

@epoberezkin
Copy link
Member

You can achieve it by nesting discriminators, or you can define a custom macro keyword to do it for you. discriminator is half-standard so changing it is probably wrong.

@pkuczynski
Copy link
Author

pkuczynski commented Jul 13, 2021

I tried nesting discriminator in the following schema:

{
    type: 'object',
    discriminator: { propertyName: 'a' },
    properties: { b: { type: 'string' } },
    required: ['a', 'b'],
    oneOf: [
       {
          properties: {
            a: { const: true }
            c: { type: 'string' }
          }
       }
       {
          properties: {
            a: { const: false }
            c: { type: 'number' }
          },
          discriminator: { propertyName: 'b' },
          oneOf: [
            {
              properties: {
                b: { const: 'b1' }
                d: { type: 'string' }
            },
            {
              properties: {
                b: { const: 'b2' }
                d: { type: 'number' }
            },
          ]
       }
    ]
}

but I am getting the error Error: discriminator: "a" values must be unique string. Seems that discriminator does not really work with boolean? Is this intended?

@epoberezkin
Copy link
Member

Yes, it only supports strings

@pkuczynski
Copy link
Author

Would you be open for a PR to support other values like numbers and boolean?

@epoberezkin
Copy link
Member

Yes - that should be doable I think - thank you!

@epoberezkin
Copy link
Member

So effectively any scalar value can be matched with discriminator and you can use the same approach as in select keyword to make them object keys, so true as string is not the same as true as Boolean. Also worth supporting null in this case.

@epoberezkin
Copy link
Member

(Select is defined in ajv-keywords for the reference)

@pkuczynski
Copy link
Author

I have seen select, but it's deprecated in favor of discriminator. So I will give it a shot next week to extend to other scalar values...

@epoberezkin
Copy link
Member

I only meant to use it to support discriminator improvement - not suggesting to use it instead. Let me know if you have any questions.

@pkuczynski
Copy link
Author

I am working on extending discriminator with other values then string. Can I use Map object or would it create compatibility issue with older browsers?

@pkuczynski
Copy link
Author

Here you go @epoberezkin #1729. Let me know what do you think?

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

No branches or pull requests

2 participants