unused-components-schema for discriminator mappings
Describe the bug
I'm getting the following warning from Spectral:
warning oas3-unused-components-schema Potentially unused components schema has been detected.
This only happens for Schemas that are only referenced in the discriminator mappings, for example:
discriminator:
propertyName: type
mapping:
spatial: '#/components/schemas/dimension_spatial'
temporal: '#/components/schemas/dimension_temporal'
bands: '#/components/schemas/dimension_bands'
other: '#/components/schemas/dimension_other'
To Reproduce
Here's the OpenAPI file I'm working on: https://github.com/Open-EO/openeo-api/blob/76ec4a59/openapi.yaml I'm running: spectral lint openapi.yaml Ruleset is spectral:oas
Expected behavior No warning.
Environment (remove any that are not applicable):
- Library version: 5.4.0
- OS: Windows 10
@m-mohr Interesting!
Few thoughts (and fair warning: I'm far from being a discriminator guru :wink:):
- https://github.com/OAI/OpenAPI-Specification/blob/b748a884fa4571ffb6dd6ed9a4d20e38e41a878c/versions/3.0.3.md#discriminator-object doco seems to describe usage of the discriminator as a way to pick one specific schema among many (described through
oneOf/anyOf). Listing all the possible schemas would make the warning disappear. Just for my understanding, what led you to choose to not list them? - There's an open discussion to potentially deprecate
discriminator(cf. https://github.com/OAI/OpenAPI-Specification/issues/2143) in favor of other approaches
There might be ways to special case discriminator/mapping in oas3-unused-components-schema but it might not be that trivial as I doubt those mapping entries will already exist as identified references.
@m-mohr I'm curious, does the valid-examples-* rule properly properly fail when the provided example expose a valid property/value pair that match the discriminator mappings but doesn't respect the rest of the subtype schema?
@philsturgeon Would you know how common it is to only expose a discriminator without listing all the possible schemas? And from another perspective, from a tooling standpoint, does schema validation even do anything meaningful in that context?
Few thoughts (and fair warning: I'm far from being a
discriminatorguru 😉):
Me neither, just learned to use it some weeks ago and struggled a lot.
- https://github.com/OAI/OpenAPI-Specification/blob/b748a884fa4571ffb6dd6ed9a4d20e38e41a878c/versions/3.0.3.md#discriminator-object doco seems to describe usage of the discriminator as a way to pick one specific schema among many (described through
oneOf/anyOf). Listing all the possible schemas would make the warning disappear. Just for my understanding, what led you to choose to not list them?
openapi-generator throws a warning if I list them also in oneOf/anyOf. I think they argue that you better define it as shown below (only discriminator) and then define the other schemas and use allOf to reference the parent schema (see below). At least that is how I made code generation work and it somewhat makes sense. Otherwise it feels it needs to generate a single class with all the properties that could be available in the oneOfs, but that's not the case.
- There's an open discussion to potentially deprecate
discriminator(cf. OAI/OpenAPI-Specification#2143) in favor of other approaches
Yes, that would be appreciated a lot as code generation currently is very messy. Unfortunately, a discussion doesn't help now. OpenAPI 3.1 is around the corner and the issue hasn't been tackled there so until we have a better solution it will take years for the spec + tooling support.
There might be ways to special case
discriminator/mappinginoas3-unused-components-schemabut it might not be that trivial as I doubt those mapping entries will already exist as identified references.
Could be, but I don't see a violation of the openAPI spec so would expect that it works as it's referenced and not unsued.
@m-mohr I'm curious, does the
valid-examples-*rule properly properly fail when the provided example expose a valid property/value pair that match the discriminator mappings but doesn't respect the rest of the subtype schema?
I need to check that, but it's likely to fail as we still use it as shown below. I'd need to remove the "sub-types" that inherit with allOf to check that, but not sure how useful it is as we we actually have these sub-types and without them it's - as you said - probably not very useful.
@philsturgeon Would you know how common it is to only expose a discriminator without listing all the possible schemas? And from another perspective, from a tooling standpoint, does schema validation even do anything meaningful in that context?
As I said above, we use it as follows. It was the only way to get reasonable results from openapi-generator.
components:
schemas:
udf_runtime:
type: object
required:
- type
- default
properties:
title:
$ref: '#/components/schemas/object_title'
description:
$ref: '#/components/schemas/description'
type:
type: string
description: |-
The type of the UDF runtime.
Pre-defined types are:
* `language` for Programming Languages and
* `docker` for Docker Containers.
The types can potentially be extended by back-ends.
default:
type: string
links:
type: array
description: |-
Links related to this runtime, e.g. external documentation.
It is highly RECOMMENDED to provide at least links with
the following `rel` (relation) types:
1. `about`: A resource that further explains the runtime,
e.g. a user guide or the documentation.
For additional relation types see also the lists of
[common relation types in openEO](#section/API-Principles/Web-Linking).
items:
$ref: '#/components/schemas/link'
discriminator:
propertyName: type
mapping:
language: '#/components/schemas/udf_programming_language'
docker: '#/components/schemas/udf_docker'
udf_programming_language:
allOf:
- $ref: '#/components/schemas/udf_runtime'
- title: Programming language
required:
- versions
properties:
default:
type: string
description: The default version. MUST be one of the keys in the `versions` object.
versions:
title: Programming language versions
description: Versions available for the programming language.
type: object
additionalProperties:
x-additionalPropertiesName: Programming Language Version
title: Programming language version
type: object
required:
- libraries
properties:
libraries:
description: >-
Map of installed libraries, modules, packages
or extensions for the programming language.
The names of them are used as the property keys.
additionalProperties:
x-additionalPropertiesName: Library Name
title: Programming language library
type: object
required:
- version
properties:
version:
type: string
description: Version number of the library.
deprecated:
type: boolean
default: false
description: |-
Specifies that the library is deprecated with the potential to be
removed in any of the next versions. It should be transitioned out
of usage as soon as possible and users should refrain from using it
in new implementations.
A link with relation type `latest-version` SHOULD be added to the
`links` and MUST refer to the library or library version that can be
used instead.
links:
type: array
description: |-
Additional links related to this library,
e.g. external documentation for this library.
It is highly RECOMMENDED to provide links with
the following `rel` (relation) types:
1. `about`: A resource that further explains the library,
e.g. a user guide or the documentation.
2. `latest-version`: If a library has been marked as deprecated,
a link should point to either a new library replacing the deprecated
library or a latest version of the library available at the back-end.
For additional relation types see also the lists of
[common relation types in openEO](#section/API-Principles/Web-Linking).
items:
$ref: '#/components/schemas/link'
udf_docker:
allOf:
- $ref: '#/components/schemas/udf_runtime'
- title: Docker container
required:
- docker
- tags
properties:
docker:
type: string
description: >-
Identifier of a Docker image on Docker Hub or a
private repository, i.e. the docker image name.
default:
type: string
description: The default tag. MUST be one of the values in the `tags` array.
tags:
type: array
description: The docker tags that are supported.
minItems: 1
items:
type: string
Here's another example of discriminator being used as such: https://github.com/OAI/OpenAPI-Specification/issues/2116