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
Ambiguity between Reference Object and PathItem Object #2635
Given following document, pathItem1 can be interpreted either as Reference Object or Path Item Object. It's hard to tell what the author intended. He could have intended for pathItem1 to be a Reference Object. Or he may have intended pathItem1 to be a Path Item Object. As Path Item Object can have exactly the same shape as Reference Object the intention of the author is lost.
Can you please advice how to approach that?
Instead of having this ambiguity and $ref field in Path Item Object, wouldn't it be cleaner to use Reference Object explicitly in every place where Path Item Object is allowed?
Current workaround could be assert the presence of $ref field and one of the other fixed fields from Path Item Object (like get, post, etc...). If assertion like that passes, we can say with limited certainty that author intended to define a Path Item Object.
I didn't notice this before. The schema doesn't validate this properly. It only allows for a Path Item Object (with no Reference Object properties) OR a Reference Object. A Path Item Object with Reference Object properties would fail validation.
What is the reason for including Reference Object properties in Path Item Object as opposed to just using a Reference Object? It's the only type that does that. It also doesn't seem very well specified. It doesn't specify how a reference works in this context, but implies that there differences from a normal Reference Object. A Reference Object has rules for merging "summary" and "description", but other properties are not merged in the referenced object. Path Item Object implies that some merging takes place, but doesn't specify how (e.g. deep or shallow merge). Is it assumed that Reference Object behaviors apply here unless otherwise specified? Do the merging rules for "summary" and "description" in a Reference Object apply?
As a workaround, I think you can always treat a $ref as part of the Path Item Object and never a Reference Object and always get what the user intended. If a Path Item Object only has Reference Object properties, it would evaluate the same as if it were a Reference Object. The only difference in processing it as a Reference Object is that any Path Item Object properties will be ignored. Since the user wouldn't include Path Item properties if they expected those properties to be ignored, we can be confident that if those properties appear, we should process it as a Path Item Object. I think that in all cases, processing it as a Path Item Object should result in the desired behavior.
@jdesrosiers it's an old remnant of version 2.0, where we allowed the reference without knowing back then that it cannot live alongside other properties. So back then (and now), it allows siblings and does not ignore them.
Granted, with 3.1, we could have used the current Reference Object and allow for siblings, but we didn't. It's one of the few places in the spec where the $ref is not JSON Schema Reference nor the Reference Object, but its own thing.
The schema doesn't validate this properly. It only allows for a Path Item Object (with no Reference Object properties) OR a Reference Object. A Path Item Object with Reference Object properties would fail validation.
So this technically means that if Object looks like a Reference Object, it will always be considered a Reference Object.
What is the reason for including Reference Object properties in Path Item Object as opposed to just using a Reference Object?
As @webron mentioned it's a remnant from older specifications, where components/pathItems fields did not exist and Paths Object only allows Path Item Object as a value of it's pattern fields. So including $ref field in Path Item Object was the only way to reference another Path Item Object from Paths Object.
It also doesn't seem very well specified. It doesn't specify how a reference works in this context, but implies that there differences from a normal Reference Object. A Reference Object has rules for merging "summary" and "description", but other properties are not merged in the referenced object. Path Item Object implies that some merging takes place, but doesn't specify how (e.g. deep or shallow merge)
As the merging rules as undefined by the specification, tooling authors have to come up with something that makes sense. I've chosen the same merging rules as Reference Object and Schema Object follows. Fields from referencing object will shallowly override fields from referenced object.
Is it assumed that Reference Object behaviors apply here unless otherwise specified? Do the merging rules for "summary" and "description" in a Reference Object apply?
Acoording to this: Allows for a referenced definition of this path item. The referenced structure MUST be in the form of a Path Item Object. In case a Path Item Object field appears both in the defined object and the referenced object, the behavior is undefined. See the rules for resolving Relative References. the Reference Oject behaviors don't apply and the behavior is undefined.
As a workaround, I think you can always treat a $ref as part of the Path Item Object and never a Reference Object and always get what the user intended.
This would contradict the current schema validation. IMHO better way and possibly more forward compatible one would be to stay with the current validation and consider everything that looks like a Reference Object a Reference Object.
If a Path Item Object only has Reference Object properties, it would evaluate the same as if it were a Reference Object. The only difference in processing it as a Reference Object is that any Path Item Object properties will be ignored. Since the user wouldn't include Path Item properties if they expected those properties to be ignored, we can be confident that if those properties appear, we should process it as a Path Item Object. I think that in all cases, processing it as a Path Item Object should result in the desired behavior.
So if I understand this correctly, whenever there there is a choice between Reference Object | Path Item Object and the Object defines a $ref field, we should always consider it a Path Item Object. This will have an implication on fields merging as Path Item Object doesn't define it and every tooling author can choose how to define the merging. It is also not aligned with current schema validation.
I still think that this is problematic and opens door for unnecessary interpretations. In order to reduce the complexity and eliminate the ambiguity I propose following:
remove $ref field from Path Item Object
define a Type for Paths Object field pattern as this: Path Item Object | Reference Object
This small change will make things right in backward compatible manner.
So this technically means that if an Object looks like a Reference Object, it will always be considered a Reference Object.
Yes. If it has a $ref, the schema will consider it a Reference Object which means that it will be invalid if it contains any additional properties other than "summary" and "description". However, the schema is non-normative so it doesn't tell us how OpenAPI should behave. If the spec and the schema disagree, the schema is wrong.
I've chosen the same merging rules as Reference Object and Schema Object follows. Fields from referencing object will shallowly override fields from referenced object.
References in a Schema Object don't do any merging (not in any version of JSON Schema). Reference Object doesn't expressly specify a shallow merge, but I think the term "override" does imply a shallow merge.
whenever there there is a choice between Reference Object | Path Item Object and the Object defines a $ref field, we should always consider it a Path Item Object. This will have an implication on fields merging as Path Item Object doesn't define it and every tooling author can choose how to define the merging.
Right. This workaround only works if the tooling uses similar merging rules to Reference Object.
I still think that this is problematic and opens door for unnecessary interpretations.
I'm sure everyone can agree with that. I completely agree with your proposed changes.
References in a Schema Object don't do any merging (not in any version of JSON Schema). Reference Object doesn't expressly specify a shallow merge, but I think the term "override" does imply a shallow merge.
Right, there is only section of 7.7.1.1 which kind of defines what the behavior could be, and that behavior is aligned with OAS 3.1 Reference Object.
I'm sure everyone can agree with that. I completely agree with your proposed changes.
Should I push this forward by creating a PR with a proposed change?
3.1.1 : 1) Remove the use of reference Object for WebHooks and Components/PathItems
2) Identify $ref on its own as a ReferenceObject
3) Make PathObjects array of PathItem | ReferenceObject
4) Deprecate the use of $ref alongside other operation fields?
3.2.: 1) Remove $ref from PathItem fixed fields?
Should we continue to support "merging" PathItems?
@darrelmiller IMHO 3.1.1 - 1 and 3.1.1 - 3 contradict each other. If our aim is to remove $ref field field from Path Item Object in next breaking change release following steps seems like more appropriate:
3.1.1
The aim here is provide clarification to limit ambiguity
Clarification - Change Type Reference Object | Path Item Object in all places within spec to Path Item Object
Deprecate the use of $ref fixed field in Path Item Object
3.2.0
The aim here is to have only one referencing mechanism iwithing OAS 3.2 spec (reducing complexity) - Referece Object (JSON Schema spec has it's own $ref mechanism)
Remove $ref from Path Item Object fixed fields
Change Type Path Item Object in all places within spec to Reference Object | Path Item Object
I've scanned ~200,000 OpenAPI documents and apart from my test file, I've found precisely 3 occurrences of a pathItem object having a $ref and one or more operation objects (all OpenAPI 2.0).
All three files are exactly the same and are in test folders of the pyswagger/pyopenapi projects:
Because the top level paths is defined as #/$defs/paths which is an object of path-items, not path-items-or-references. I think we could resolve all issues by letting /paths/<path> be an object of path-items-or-references, and amending the spec to match.
I think that change would cover any real use cases, but I don't think it completely brings the schema in line with the spec. That change would not allow properties next to $ref other than description and summary (as defined by ReferenceObject), but the PathItemObject seems to allow any properties that are part of PathItemObject alongside the $ref (even tho it's undefined how to interpret those properties).
The get the specified behavior, I think we'd have to add $ref the PathItem schema and change path-item-or-reference to be use anyOf instead of if/then.
Activity
jdesrosiers commentedon Jul 1, 2021
I didn't notice this before. The schema doesn't validate this properly. It only allows for a Path Item Object (with no Reference Object properties) OR a Reference Object. A Path Item Object with Reference Object properties would fail validation.
What is the reason for including Reference Object properties in Path Item Object as opposed to just using a Reference Object? It's the only type that does that. It also doesn't seem very well specified. It doesn't specify how a reference works in this context, but implies that there differences from a normal Reference Object. A Reference Object has rules for merging "summary" and "description", but other properties are not merged in the referenced object. Path Item Object implies that some merging takes place, but doesn't specify how (e.g. deep or shallow merge). Is it assumed that Reference Object behaviors apply here unless otherwise specified? Do the merging rules for "summary" and "description" in a Reference Object apply?
As a workaround, I think you can always treat a
$refas part of the Path Item Object and never a Reference Object and always get what the user intended. If a Path Item Object only has Reference Object properties, it would evaluate the same as if it were a Reference Object. The only difference in processing it as a Reference Object is that any Path Item Object properties will be ignored. Since the user wouldn't include Path Item properties if they expected those properties to be ignored, we can be confident that if those properties appear, we should process it as a Path Item Object. I think that in all cases, processing it as a Path Item Object should result in the desired behavior.webron commentedon Jul 1, 2021
@jdesrosiers it's an old remnant of version 2.0, where we allowed the reference without knowing back then that it cannot live alongside other properties. So back then (and now), it allows siblings and does not ignore them.
Granted, with 3.1, we could have used the current Reference Object and allow for siblings, but we didn't. It's one of the few places in the spec where the
$refis not JSON Schema Reference nor the Reference Object, but its own thing.char0n commentedon Jul 2, 2021
So this technically means that if Object looks like a Reference Object, it will always be considered a Reference Object.
As @webron mentioned it's a remnant from older specifications, where
components/pathItemsfields did not exist andPaths Objectonly allowsPath Item Objectas a value of it's pattern fields. So including$reffield inPath Item Objectwas the only way to reference anotherPath Item ObjectfromPaths Object.As the merging rules as
undefinedby the specification, tooling authors have to come up with something that makes sense. I've chosen the same merging rules asReference ObjectandSchema Objectfollows. Fields from referencing object will shallowly override fields from referenced object.Acoording to this:
Allows for a referenced definition of this path item. The referenced structure MUST be in the form of a Path Item Object. In case a Path Item Object field appears both in the defined object and the referenced object, the behavior is undefined. See the rules for resolving Relative References.the Reference Oject behaviors don't apply and the behavior is undefined.This would contradict the current schema validation. IMHO better way and possibly more forward compatible one would be to stay with the current validation and consider everything that looks like a Reference Object a Reference Object.
So if I understand this correctly, whenever there there is a choice between
Reference Object | Path Item Objectand the Object defines a$reffield, we should always consider it aPath Item Object. This will have an implication on fields merging as Path Item Object doesn't define it and every tooling author can choose how to define the merging. It is also not aligned with current schema validation.I still think that this is problematic and opens door for unnecessary interpretations. In order to reduce the complexity and eliminate the ambiguity I propose following:
$reffield fromPath Item ObjectTypeforPaths Objectfield pattern as this:Path Item Object | Reference ObjectThis small change will make things right in backward compatible manner.
jdesrosiers commentedon Jul 2, 2021
Yes. If it has a
$ref, the schema will consider it a Reference Object which means that it will be invalid if it contains any additional properties other than "summary" and "description". However, the schema is non-normative so it doesn't tell us how OpenAPI should behave. If the spec and the schema disagree, the schema is wrong.References in a Schema Object don't do any merging (not in any version of JSON Schema). Reference Object doesn't expressly specify a shallow merge, but I think the term "override" does imply a shallow merge.
Right. This workaround only works if the tooling uses similar merging rules to Reference Object.
I'm sure everyone can agree with that. I completely agree with your proposed changes.
char0n commentedon Jul 5, 2021
Right, there is only section of 7.7.1.1 which kind of defines what the behavior could be, and that behavior is aligned with OAS 3.1 Reference Object.
Should I push this forward by creating a PR with a proposed change?
Thank you for your time and all the answers!
darrelmiller commentedon Jul 8, 2021
From TDC call:
3.1.1 : 1) Remove the use of reference Object for WebHooks and Components/PathItems
2) Identify $ref on its own as a ReferenceObject
3) Make PathObjects array of PathItem | ReferenceObject
4) Deprecate the use of $ref alongside other operation fields?
3.2.: 1) Remove $ref from PathItem fixed fields?
Should we continue to support "merging" PathItems?
char0n commentedon Jul 9, 2021
@darrelmiller IMHO
3.1.1 - 1and3.1.1 - 3contradict each other. If our aim is to remove$reffield field fromPath Item Objectin next breaking change release following steps seems like more appropriate:3.1.1
The aim here is provide clarification to limit ambiguity
Reference Object | Path Item Objectin all places within spec toPath Item Object$reffixed field inPath Item Object3.2.0
The aim here is to have only one referencing mechanism iwithing OAS 3.2 spec (reducing complexity) -
Referece Object(JSON Schema spec has it's own $ref mechanism)Path Item Objectfixed fieldsPath Item Objectin all places within spec toReference Object | Path Item ObjectMikeRalphson commentedon Jul 9, 2021
I've scanned ~200,000 OpenAPI documents and apart from my test file, I've found precisely 3 occurrences of a
pathItemobject having a$refand one or moreoperationobjects (all OpenAPI 2.0).All three files are exactly the same and are in test folders of the pyswagger/pyopenapi projects:
char0n commentedon Jul 12, 2021
During the next week I should have some numbers from SwaggerHub as well.
Provide clarification for limit Path Item abiguity (OAI#2635)
Provide clarification to limit Path Item abiguity (OAI#2635)
Provide clarification to limit Path Item ambiguity (OAI#2635)
Deprecate Path Item Object ref field (OAI#2635)
Allow referencing Path Item only via Reference Object (OAI#2635)
8 remaining items
Allow referencing Path Item only via Reference Object (#2635) (#2657)
Provide clarification to limit Path Item ambiguity (#2635) (#2655)
Deprecate Path Item Object ref field (OAI#2635) (OAI#2656)
Provide clarification to limit Path Item ambiguity (OAI#2635) (OAI#2655)
Deprecate Path Item Object ref field (OAI#2635) (OAI#2656)
Provide clarification to limit Path Item ambiguity (OAI#2635) (OAI#2655)
karenetheridge commentedon Jun 9, 2023
What's the status of this? It appears to have stalled just before execution of all the action items listed.
jdesrosiers commentedon Jun 19, 2023
I think that change would cover any real use cases, but I don't think it completely brings the schema in line with the spec. That change would not allow properties next to
$refother thandescriptionandsummary(as defined by ReferenceObject), but the PathItemObject seems to allow any properties that are part of PathItemObject alongside the$ref(even tho it's undefined how to interpret those properties).The get the specified behavior, I think we'd have to add
$refthe PathItem schema and changepath-item-or-referenceto be useanyOfinstead ofif/then.fix: Correctly validate paths using $ref (#2485)