You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Discriminator: how properly detect valid reference #2520
servers:
- url: 'http://example.com/'components:
schemas:
Pet:
type: objectrequired:
- petTypeproperties:
petType:
type: stringdiscriminator:
propertyName: petTypemapping:
dog: DogCat:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object# all other properties specific to a `Cat`properties:
name:
type: stringDog:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object# all other properties specific to a `Dog`properties:
bark:
type: stringLizard:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object# all other properties specific to a `Lizard`properties:
lovesRocks:
type: boolean
it is not clear what mean Dog in the mapping subscheme.
Variants:
If i have subschema in another url (http://example.com/openapi/Dog) thеn Dog is relative link.
If i have subschema in components thеn Dog is #/components/schemas/Dog (which is also a relative link, but different)
How to correctly determine that Dog is a relative link or subschema in #/components/schema?
I believe is example has a bug. The values of mapping are URIs that must match the URI of one of the schemas being discriminated. I don't think OpenAPI has a concept of an identifier the way JSON Schema does. In that case, Dog doesn't have anything to resolve against and that is an invalid reference. If OpenAPI does have a concept of an identifier, then it would resolve to http://example.com/openapi/Dog, which doesn't exist. Constructing #/components/schemas/Dog should only happen when auto mapping, not with mapping.
This example is taken from the specification (see the example in the end of discriminator object), i.e. I have not invented it. I understand correctly that you want to say that this is a bug in the documentation description (or bug in example in documentation)?
If the construction of the #/components/schemas/Dog will be done only with auto-mapping, then in my opinion this will solve the problem too. In such case mapping MUST have ONLY reference, so my example MUST resolve it via http://example.com/openapi/Dog (based on base uri http://example.com/openapi/desc).
At the moment I'm trying to figure out, should I handle this situation like this, or is it under discussion?
I didn't think you made it up. I recognized it as the example is from the documentation. Yes, I believe the example from the documentation has a bug.
I don't think that OpenAPI has a concept of a base URI, so I don't think you can resolve Dog against http://example.com/openapi/desc. I think Dog is just an invalid reference. It needs to be an absolute URI. I could be wrong about that part.
I don't think that OpenAPI has a concept of a base URI
Hmm... Maybe i misunderstood the documentation. Pay attention to part of the specification Relative References in URLs. For me, this part is not very clear and requires clarification.
From specification:
Relative references are resolved using the URLs defined in the Server Object as a Base URI.
I think what is meant here is about url in the subscheme paths (i do not know of any other examples of what this might mean, for me it is not clear).
There is a special note for $ref:
Relative references used in $ref are processed as per JSON Reference, using the URL of the current document as the base URI
Thus, if OpenAPI is served by url http://example.com/openapi/desc, then it is the base url for $ref. It means that you may to split your OpenAPI description for several files like this:
Suppose that this OpenAPI description served by url http://example.com/openapi/main.yml, then
'http://example.com/' is a base URI for /company, so absolute url is 'http://example.com/company'. 'http://example.com/openapi/main.yml' is a base URI for 'company.yml#/paths/~1company', so absolute url is 'http://example.com/openapi/company.yml#/paths/~1company'
I was wrong that "schema names" are not allowed in mapping. The spec says mapping is "an object to hold mappings between payload values and schema names or references". (The spec never defines what "schema names" means, but it's assumed that it means the property names used under /components/schemas which is equivalent to #/components/schemas/{schema name}.) Since a schema name is also a valid URI, there definitely seems to be an ambiguity in the spec.
I think the most reasonable thing to do would be to assume it's a schema name if it looks like a schema name and fallback to treating it like a URI if that schema doesn't exist. It would be nice if there was a linting rule to flag the use of schema names in mapping as something to be avoided.
Activity
Logioniz commentedon Apr 12, 2021
Any recommendations?
Not sure how to properly handle this kind of situation.
jdesrosiers commentedon Apr 12, 2021
(Note: I deleted my previous wrong response)
I believe is example has a bug. The values of
mappingare URIs that must match the URI of one of the schemas being discriminated. I don't think OpenAPI has a concept of an identifier the way JSON Schema does. In that case,Dogdoesn't have anything to resolve against and that is an invalid reference. If OpenAPI does have a concept of an identifier, then it would resolve tohttp://example.com/openapi/Dog, which doesn't exist. Constructing#/components/schemas/Dogshould only happen when auto mapping, not withmapping.The discriminator in the example should be,
Logioniz commentedon Apr 13, 2021
This example is taken from the specification (see the example in the end of discriminator object), i.e. I have not invented it. I understand correctly that you want to say that this is a bug in the documentation description (or bug in example in documentation)?
If the construction of the
#/components/schemas/Dogwill be done only with auto-mapping, then in my opinion this will solve the problem too. In such casemappingMUST have ONLY reference, so my example MUST resolve it via http://example.com/openapi/Dog (based on base uri http://example.com/openapi/desc).At the moment I'm trying to figure out, should I handle this situation like this, or is it under discussion?
jdesrosiers commentedon Apr 13, 2021
I didn't think you made it up. I recognized it as the example is from the documentation. Yes, I believe the example from the documentation has a bug.
I don't think that OpenAPI has a concept of a base URI, so I don't think you can resolve
Dogagainsthttp://example.com/openapi/desc. I thinkDogis just an invalid reference. It needs to be an absolute URI. I could be wrong about that part.Logioniz commentedon Apr 14, 2021
@jdesrosiers thanks for your reply.
Hmm... Maybe i misunderstood the documentation. Pay attention to part of the specification Relative References in URLs. For me, this part is not very clear and requires clarification.
From specification:
I think what is meant here is about url in the subscheme
paths(i do not know of any other examples of what this might mean, for me it is not clear).There is a special note for
$ref:Thus, if OpenAPI is served by url http://example.com/openapi/desc, then it is the base url for
$ref. It means that you may to split your OpenAPI description for several files like this:Suppose that this OpenAPI description served by url
http://example.com/openapi/main.yml, then'http://example.com/'is a base URI for/company, so absolute url is'http://example.com/company'.'http://example.com/openapi/main.yml'is a base URI for'company.yml#/paths/~1company', so absolute url is'http://example.com/openapi/company.yml#/paths/~1company'jdesrosiers commentedon Apr 14, 2021
I agree with your conclusion. This is what I missed,
That is very clear. So, I agree that in the previous example,
Dogwould resolve tohttp://example.com/openapi/Dog.karenetheridge commentedon Oct 13, 2021
This appears to have been fixed in the spec now. https://spec.openapis.org/oas/v3.1.0#discriminator-object has the example:
where the dog mapping properly has the uri reference, rather than just a snippet "Dog".
MaceWindu commentedon May 27, 2022
No, it wasn't. Last example still use
DogBTW, I've come here, because I've stumbled upon real openapi document which use this notation https://github.com/LandRegistry/digital-street-conveyancer-api/blob/master/src/main/resources/openapi.json#L730-L731
and expect it resolved to
#/components/schemas/<name>...jdesrosiers commentedon May 27, 2022
I was wrong that "schema names" are not allowed in
mapping. The spec saysmappingis "an object to hold mappings between payload values and schema names or references". (The spec never defines what "schema names" means, but it's assumed that it means the property names used under/components/schemaswhich is equivalent to#/components/schemas/{schema name}.) Since a schema name is also a valid URI, there definitely seems to be an ambiguity in the spec.I think the most reasonable thing to do would be to assume it's a schema name if it looks like a schema name and fallback to treating it like a URI if that schema doesn't exist. It would be nice if there was a linting rule to flag the use of schema names in
mappingas something to be avoided.handrews commentedon Jun 6, 2024
PRs merged! closing.