Skip to content

Conversation

@ioggstream
Copy link
Collaborator

This PR

@handrews
Copy link
Collaborator

I think that OAS 3.0 is the first specification with a standardization base,

What does this mean, exactly? OAS 2.0 (which was a tiny bit different from Swagger 2.0, but mostly just small fixes to errors) was the first version released under the OpenAPI Initiative. So it's as standardized as 3.0 or 3.1.

and referencing 2.0 does not help interoperability.

Didn't we define a version media type parameter for content negotiation on this? While I hate that this is true, there are still tools out there that can't use anything after 2.0. I'd love to do anything and everything to make 2.0 go away, but I'm not sure that forbidding it here will really help that goal. And it seems to prevent people who might want to try to bridge 2.0 to 3.x from making an effort in a standardized way that is consistent with what they will do to bridge 3.0 to 3.1+, or to 4.0

Moreover, it's in an FAQ that will be removed at publication.

Does this mean that in practice, 2.0 is not excluded? I'm a bit confused.

@ioggstream
Copy link
Collaborator Author

forbidding it here will really help that goal. And it seems to prevent people who might want to try to bridge 2.0 to 3.x

This makes sense, but I think that migration should be the only reason for that.

Actually, using version: 2.0 is not "forbidden". Just "undefined" here, because:

  • I did no proof-reading of the spec wrt OAS 2.0 and there are no statements such as:

dependently on the OAS version, the keyword associated with the version is different between 2.0 (swagger) and 3+ (openapi) ...

  • I don't know whether the terms of "OAD", "OAd", ... are still valid for v2.0...
  • 2.0 tools generally use application/vnd.swagger.whatever

Anyway, I'm not that into v2.0, but if you/ @darrelmiller think that this document suits OAS 2.0, we can extend the scope.

@ioggstream ioggstream force-pushed the ioggstream-110-quat branch from 9c04640 to 76c3820 Compare March 18, 2025 09:06
Comment on lines +270 to +273
A server can publish an OpenAPI resource that
does not contain an "OpenAPI Object".
In this case, the `version` parameter is useful to identify
the specification version.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is talking about using the version parameter in the Content-Type header of a response, or a similar usage, correct? Should this be made more clear when initially discussing the parameter usage? What happens when a version paramter is used in this way with an OpenAPI Document (with an OpenAPI Object) where the openapi field disagrees with the version parameter? "Disagrees" here needs to be handled with the same concerns over compatibility and version matching that I just brought up in #124.

Copy link
Collaborator Author

@ioggstream ioggstream Mar 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using the version parameter in the Content-Type header of a response

Yes, this is stated in the document introduction: can you please check if it's clear enough here?

What happens when a version paramter disagrees with the version [specified in the OpenAPI object]

I think prescribing a behavior may go beyond the scope of the media type registration,
since:

  • it is responsibility of the sender to ensure the correct value of the media type;
  • it is a choice of the client to decide the tolerance threshold according to its use case.

Maybe the above wording could fit the Interoperability considerations.

Agree to discuss this further in #124.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The no-OpenAPI Object part might be good for interoperability. Again, we streamlined how we talked about this in 3.2 so I will go over this in that context and see if it all still makes sense. But I think the direction of this PR is correct.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

@handrews If you think we can merge and refine after, I'll rebase.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ioggstream I'm trying to figure out what out of the following needs to be in here, and how to say it concisely (this really spans both this PR and #125):

  • The terminology OpenAPI Description and OpenAPI Document was introduced in 3.0.4 and 3.1.1, although as patch releases replace earlier patch releases in the same minor release line, the documented behavior is intended to apply to all 3.0 and 3.1+ versions.
  • In 3.2, we dropped the distinction between capital-D "Document" and lowercase-d "document" by banishing guidance on former lowercase-d "document" to an appendix that mostly says "don't do this." So looking for a capital-D "Document" term in 3.2 might be confusing, and maybe we want to go with the 3.2 approach?
    • It might be better to talk in terms of whether an OpenAPI Object is at the document root or not? That's really what the distinction is. Or a Schema Object at the root, but we can hand-wave that as a JSON Schema document, I think.
  • Regardless of the terminology, there are considerable ambiguities in the parsing rules for multiple documents 3.0
    • This is partly because the assumed-but-never-quite-fully-documented parsing rules in 2.0 were very different from those in 3.1. As @darrelmiller once noted, 3.0 is in an "uncanny valley" situation because the 2.0 wording was removed, but no clear wording was added.
    • 2.0 treates the OpenAPI Description as a single document, regardless of its actual document structure. There is no good way to square this with how resources and media types actually work. For example, in 2.0, you do not parse the entire referenced document, only the specific reference object, which is de-facto inlined. How this was supposed to work with recursive references was never really explained.
    • All of this means that multi-document OAD parsing is probably either not very well-defined, or not very compatible with how URIs, documents, and resources work for versions prior to 3.1. 3.1.0 is not as clear as it could be, but the intended behavior is (more or less) well-defined. 3.2 is the most clear and well-defined.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ioggstream on second thought, didn't we decide that the media type only applies to documents with an OpenAPI Object (and therefore openapi field) at the root? Documents that are just Schema Objects would have JSON Schema's media type. Documents that are some other Object type would not have a media type.

Copy link

@karenetheridge karenetheridge Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, if there is no openapi object at the root it's not an OpenAPI document, but just a JSON Schema document, so it would be application/schema+json. We could have a version parameter in the media type for that file, but the $schema keyword in the document itself is a more reliable way of determining the version.

Copy link
Collaborator Author

@ioggstream ioggstream Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't we decide that the media type only applies to documents with an OpenAPI Object

IIRC we did not assume that this only applies to documents with an OpenAPI Object.

A document containing an Object Schema with OAS-specific keywords/extensions may not be a JSON Schema object (and we can't reference a JSON Schema media type yet).

The following is an OAS3.0 schema: https://opensource.zalando.com/problem/schema.yaml

Copy link

@karenetheridge karenetheridge Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following is an OAS3.0 schema: https://opensource.zalando.com/problem/schema.yaml

It's an OAS schema (edit: no it isn't even that -- but it would be if you removed the top level property "Problem"), but it is not a valid OAS document. It cannot be validated with the OAS 3.0 metaschema. While you may be able to $ref into it from an openapi document, it cannot be parsed as an openapi document on its own. To do that, you should move that top level object to live under /components/schemas, and add the required top level properties /openapi, /info and /paths. (In 3.1+, you don't need /paths if you have /components.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ioggstream to add to @karenetheridge 's example, that document is a valid JSON Schema document (which would use the JSON Schema media type) using the OAS vocabulary (which does not require a distinct media type). It is not a valid OpenAPI document. In OAS so far, all Schema Objects are valid JSON Schemas (although in 2.0 and 3.0 the status of the extension keywords added by the OAS was unclear, but that's because JSON Schema draft-04 was unclear about extensions, not because the extensions made them invalid JSON Schemas.

IIRC we did not assume that this only applies to documents with an OpenAPI Object.

We excluded non-OpenAPI Object-rooted documents in issue #110.

@handrews handrews mentioned this pull request Nov 26, 2025
2 tasks
Comment on lines +254 to +266
## Media type of referenced resources

An OpenAPI Description can reference external resources
that are not OpenAPI Documents (e.g., JSON Schema documents).
Clients should be aware that
even if they request a specific media type for those resources
(e.g., `Accept: application/openapi+yaml; version=3.1`),
the server might only be able to provide a more generic media type.

For example, a server that publishes a JSON Schema file,
which can be referenced by both OpenAPI and JSON Schema documents,
might choose to use the more generic `application/yaml` media type
instead of managing multiple specific media types for the same resource.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@handrews if we agree on this, let's split and merge this part of the PR.

Copy link
Collaborator

@handrews handrews Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to figure out the cases in my head, as something is bugging me here but I can't quite figure it out. There are few possible reference targets:

  1. An OAD document (with an OpenAPI Object at the root) (application/openapi+json or application/openapi+yaml)
  2. A JSON Schema document (a Schema Object in its own file) (application/schema+json or whatever we use for schemas, but NOT application/openapi+json)
  3. A different type of Object (e.g. Path Item Object) in its own file (This case has no media type more specific than application/json or application/yaml)
  4. Some other sort of document used for external docs (External Documentation Object url) or examples (Example Object externalValue) (media type determined as usual- possibly text/html for external docs, while the example could be literally anything, depending on what it is an example of).

Cases 1, 2, and 4 are well-defined.

In the case of 1 and 2, the usual caveats apply, namely that a more generic media type might be returned rather than the specific one with the structured suffix. I don't think there's anything special going on there compared to any other situation where you would ask for a +json and might get back application/json even though the contents are correct for the requested +json format.

For case 3, this is the thing that we may or may not want to mention as possible at all. In #110, it appears we decided to not mention it as a way to discourage people attempting such document organization (it's never necessary in 3.1+, but in 3.0 you can't put Path Item Objects in the Components Object, so people often put then in separate files).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I don't think we should allow 3 at all. It has no media type and it isn't obvious even from visual inspection what type of object(s) it contains, so I don't think it could be reliably parsed.

Remember, it's not enough to just simply load the file and decode its yaml or json and consider it a $refable target -- an implementation needs to know what type of object it is so it can examine it for embedded schemas (which can contain $id and $anchor keywords which can be used by $ref keywords in other schemas in the OAD); and in the case of operation objects, examine it for operationId keywords (which are referenceable by link objects, as well possibly by outside code e.g. client/code generators).

Also, surprising things might happen if an implementation tries to $ref to a particular object and it is the wrong type -- it is much easier to know the kind of all objects so we can prevent $refs from going to the wrong place before we try to evaluate the keywords found there -- it saves a lot of error checking in the target code, which can just assume that it's using the right type. (In my implementation I keep a table of OAD locations -> entity type, which is easily constructed while performing the initial parse and validation pass on the document, and throw an error if a $ref tries to go the wrong type.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@karenetheridge

an implementation needs to know what type of object it is so it can examine it for embedded schemas

Also, surprising things might happen if an implementation tries to $ref to a particular object and it is the wrong type

This is addressed in the "Structural Interoperability" sections in 3.0.4, 3.1.2 (and 3.1.1), and the first two subsections of Appendix G of 3.2.

When I mentioned parsing and referencing ambiguities earlier in this thread, @ioggstream commented:

These should probably be left to the relevant OAS specs. We can just warn implementers.

which is probably the best way to handle these details. Older implementations try to do these things, and either deal with it already or don't. Newer implementations should be coming from the 3.1.1+ / 3.2+ world and shouldn't do them at all, and therefore shouldn't have these problems anyway.

@ioggstream
Copy link
Collaborator Author

@ilovelinux enjoy

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants