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

Limit anyOf/oneOf discriminator to listed refs #145

Merged
merged 3 commits into from
Oct 13, 2023
Merged

Conversation

davishmcclurg
Copy link
Owner

This addresses an issue where resolve_ref gets called for refs that
aren't explicitly listed in anyOf or oneOf. The specification
says:

In both the oneOf and anyOf use cases, all possible schemas MUST be listed explicitly.

So for anyOf/oneOf discriminators, this uses the provided refs to build
a mapping of property values to schema objects for lookup during
validation. Explicit mappings are found by schema name or full ref to
support:

discriminator:
  propertyName: petType
  mapping:
    cat: Cat
    dog: '#/components/schemas/Dog'

Impicit mappings are only created for refs under #/components/schemas/
and are overridden by any explicit mappings that point to the same
schema.

allOf discriminators still resolve refs because there isn't an
explicit list of allowed refs. Switched to Schema#ref now that it
calls root.resolve_ref itself.

FIXED_FIELD_REGEX comes from the spec:

All the fixed fields declared above are objects that MUST use keys that match the regular expression: ^[a-zA-Z0-9.-_]+$.

It's used in all cases to make sure schemas are only looked up by name
if the property value is a valid schema name.

Closes: #144

https://spec.openapis.org/oas/v3.1.0#discriminator-object

> The expectation now is that a property with name petType MUST be present in the response payload

It's a little unclear because the specification examples mostly specify
the `propertyName` property under `required` as well, which seems
redundant. It's probably safer this way, though, and the spec says
"MUST" so we must.
`resolve_ref` needs to be called on the root schema because that's where
all the `resources` are stored.

The behavior here is kind of confusing because the ref is resolved just
like the `$ref` keyword would be in the schema, so it's dependent on the
schema's base URI. That means for a subschema `ref('#')` doesn't
necessarily resolve to itself (ie, if the subschema doesn't have `$id`).
This addresses an issue where `resolve_ref` gets called for refs that
aren't explicitly listed in `anyOf` or `oneOf`. The [specification][0]
says:

> In both the oneOf and anyOf use cases, all possible schemas MUST be listed explicitly.

So for anyOf/oneOf discriminators, this uses the provided refs to build
a mapping of property values to schema objects for lookup during
validation. Explicit mappings are found by schema name or full ref to
support:

```yaml
discriminator:
  propertyName: petType
  mapping:
    cat: Cat
    dog: '#/components/schemas/Dog'
```

Impicit mappings are only created for refs under `#/components/schemas/`
and are overridden by any explicit mappings that point to the same
schema.

`allOf` discriminators still resolve refs because there isn't an
explicit list of allowed refs. Switched to `Schema#ref` now that it
calls `root.resolve_ref` itself.

`FIXED_FIELD_REGEX` comes from the [spec][1]:

> All the fixed fields declared above are objects that MUST use keys that match the regular expression: ^[a-zA-Z0-9\.\-_]+$.

It's used in all cases to make sure schemas are only looked up by name
if the property value is a valid schema name.

Closes: #144

[0]: https://spec.openapis.org/oas/v3.1.0#discriminator-object
[1]: https://spec.openapis.org/oas/v3.1.0#components-object
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

Successfully merging this pull request may close these issues.

1 participant