-
Notifications
You must be signed in to change notification settings - Fork 4
Fix: #110. Interoperability considerations instead of new parameter #121
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
base: main
Are you sure you want to change the base?
Conversation
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.
Didn't we define a
Does this mean that in practice, 2.0 is not excluded? I'm a bit confused. |
This makes sense, but I think that migration should be the only reason for that. Actually, using
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. |
9c04640 to
76c3820
Compare
| ## 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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:
- An OAD document (with an OpenAPI Object at the root) (
application/openapi+jsonorapplication/openapi+yaml) - A JSON Schema document (a Schema Object in its own file) (
application/schema+jsonor whatever we use for schemas, but NOT)application/openapi+json - A different type of Object (e.g. Path Item Object) in its own file (This case has no media type more specific than
application/jsonorapplication/yaml) - Some other sort of document used for external docs (External Documentation Object
url) or examples (Example ObjectexternalValue) (media type determined as usual- possiblytext/htmlfor 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).
There was a problem hiding this comment.
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.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@handrews this new text provides:
- a way to express the client preference for referenced resources in terms of OAS entry document (e.g.,
Accept: application/openapi+yaml; version=3.0 - the server to reply with the appropriate media type for the actual returned resource (e.g.,
Content-Type: application/yaml).
Since application/schema+json is not defined yet, and it has no associated parameters, I'd just use application/whatever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replying to @handrews @karenetheridge comment from an outdated thread
@ioggstream this does not address the concerns that @karenetheridge and I have been raising about using the same media type for different formats. I can't support this direction.
In the latest text above I tried to address this, and it does not use the same media type for different formats;
instead allows the client to express the preferred media type for a resource.
The client doesn't know the media type of a $ref until the response arrives,
and content negotiation does not involve fragments because:
- fragments are processed by User Agents
- they do not appear in requests (see https://www.rfc-editor.org/rfc/rfc9110.html#uri.fragment.identifiers and https://www.rfc-editor.org/rfc/rfc9110.html#name-disclosure-of-fragment-afte)
This means that:
$ref: foo.yaml#/components/schemas/Footriggers the following request;- the server doesn't know that the client just wants the
#/components/schemas/Foofragment; - it can reply with whatever media type it deems appropriate for the resource it is serving
GET /foo.yaml
Accept: application/openapi+yaml; version=3.0
...If we want to allow treating documents with other Object types as root objects,
we need a parameter indicating the expected root Object type, or something
similar. I believe @karenetheridge, @darrelmiller , and I are all aligned on
the principle that only a document with an OpenAPI Object at the root is an
unqualified application/openapi+* resource.
This should be addressed via https://github.com/ietf-wg-httpapi/mediatypes/pull/121/files#diff-b22c3a369e1499074590046ad01b71334e21c491c64ccf045f8858e2d3036e56R266
Reference to Schema Objects have been removed.
@ioggstream I would like to hear you address the objections @darrelmiller raised in #110 (comment) — while you have stated your goal several times, you have not addressed the objections.
IMHO the text above does not formalize the existence of fragments of OAS documents,
and the section mentioning "partial" resources present in the previous version of this PR has now been removed.
Thanks again everyone for your help in addressing this topic ❤️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ioggstream I appreciate that you are operating in good faith here, but I do not feel we are getting much closer to agreement. Perhaps there is a bit of a language barrier issue going on, but also I do not feel like we've really sorted out the concepts here, and we're not going to be able to agree on PR text until we agree on the concepts.
Since this discussion is not moving us forward, I'm going to put up an alternative PR to better illustrate my concerns. We don't necessarily have to merge that PR, but maybe it will at least get us to the point where we're not talking past each other, which I feel is what is happening now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@handrews OK. Can you include a content negotiation exchange to your PR, e.g. maybe in a FAQ or in an example :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ioggstream I have not been able to write up a PR today but I have worked through more thoughts and will come back with an update hopefully tomorrow. Please bear with me, my schedule is rather complicated at the moment.
|
@ilovelinux enjoy |
23e1da7 to
0f829b4
Compare
|
@ioggstream let's take a big step back and try to sort out the conceptual framework here. My understanding of content negotiation is basically as follows (ignoring multiple media types using
There are, of course, several ways in which this might not quite happen:
Regarding the "more generic media type" option, my expectation if I were writing a client is that the So if I request I have never seen anything where you ask for media type and get back something that does not conform to that media type at all, and then somehow you are expected to handle it anyway. A document that contains some other Object at its root is in this category. Note that this has nothing to do with URI fragments. Retrieving a representation with an OpenAPI Object at the root and then using a fragment to access an Object of a different type within that document is fine. No one has an issue with that. It's only when the root Object type is different. To me, returning a non-OpenAPI-Object-rooted document when
The above statement is not compatible with the OAS, particularly not 2.0 and 3.0. In 2.0 it is explicitly given that the Please do not ask me to explain or defend this decision, as I was not involved and put a great deal of effort into removing it or at least discouraging it in OAS 3.1+. Recent versions of the OAS explain how this can be a problem (3.0.4, similar sections exist in 3.1.1, 3.1.2, and 3.2.0). So not only is it untrue that the client doesn't know what media type to expect, it is actually the server which has no idea what the semantics are of the document being returned. Only the client has the context for interpreting the document. This means that only the client is fully capable of realizing that In fact, the same resource might parse either as a valid Path Item Object or as a valid Schema Object, and OAS 2.0 implementations (and many OAS 3.0 implemenations, and possibly 3.1+ implementations) will happily do exactly that. Particularly in 3.0 and earlier, the Object Type is determined by the referencing context. Again, don't ask me to defend this. I bashed my head against it for years. There are long discussions of this on the OpenAPI Slack. This is definitely what the Swagger folks intended, according to multiple people involved at the time.
Yes, @karenetheridge and I are well aware of this, we are not talking about URI fragments at any point here, although it's understandable that you would think so. There are difficulties involving fragments and the 2.0 / 3.0 parsing models, they are not relevant here. "Fragmentary documents" are just documents without an OpenAPI Object at the root, they have nothing to do with URI fragments.
Because a "fragment of an OAS document" is just a document with something other than an OpenAPI Object at the root, and you are trying to treat such documents as valid resposnes to In OAS 3.1 and 3.2, we get around this by treating standalone Schema Objects as JSON Schema resources, and saying that all other Object types are only interoperable if they are in a proper OpenAPI document with an OpenAPI Object at the root. |
|
@handrews Thanks for your long reply.
This can be pointed at in the Interoperability Considerations.
I understand your point of view, but I re-read the whole HTTP and I do not agree (see https://www.rfc-editor.org/rfc/rfc9110.html#section-12.4.3).
While it is ok to state that the media type openapi+yaml only applies to OpenAPI Objects, |
I don't agree with your reading. If you're dead-set on this, I'll post a PR to remove my name from this RFC. I think it is the wrong approach, and there are better options that serve the use case more clearly, with much better control and more self-descriptive media types. You seem uninterested in engaging with the alternate suggestions. I have not heard anything from you about why a Regardless, I do not want my name on a spec that requires using I'm plenty willing to add mechanisms to work around the limitations of 3.0, but I can't support an approach that, in my view, undermines my own work. And violates what I think is the spirit of content negotiation. |
So I think Henry is saying "if you send an I think the problem here is that it is not unambiguously obvious which type of document needs to be requested, based solely on the URI, without using heuristics on the json pointer fragment. Intuitively, I know that Roberto seems to be saying "just ask for application/openapi+json, and maybe you'll get something else back instead, and that's ok" and Henry is saying "that's not ok". Did I capture this dilemma correctly? [minor edits for typos] edit 2:
|
|
(I edited my last response - please read in web rather than email) |
|
Thanks, @karenetheridge , you are correct, and you bring up a good point about the ambiguity. Which (as you know) is why we say in more recent versions of the OAS that you can only be sure to understand a referenced document if it:
So there are two problems here: First, how to ask for the right thing?Sometimes you know what to ask for, down to the Object type, but sometimes you don't. I do not object to using This "what to ask for" ambiguity hasn't been called out as clearly before, so thanks for that! I feel like it is the easier half. Second, how do you know what you've gotten back?As @karenetheridge has observed in her second edit, this is where the main disconnect is. I don't want something without an OpenAPI Object at the root to be given One possibility is that it comes back as The final case is where the disconnect is: The document has neither an OpenAPI Object nor a JSON Schema at the root, e.g. the case that is necessary in OAS 3.0 of having a Path Item Object in its own document/resource. @ioggstream seems to be saying "that's fine, just send back And this is where my point of "I'm willing to put in things to work around OAS 3.0's limitations" come in. It's fairly compatible with 3.0 (and definitely 2.0) to just parse some YAML and attempt to interpret the portion of the file that was referenced as whatever it is. So But I really, really, really do not want to encourage this behavior in 3.1 and later. I don't want to imply that this is correct behavior when asking for documents because we've tried so hard to move away from that. Maybe there's no other option. But I'd prefer to be able to reply But I don't want that to be endorsed. I want servers that return known OpenAPI content to be able to indicate that in the |
|
OK, so... attempting to be productive and realistic here.
For example, I would rather say that a schema could be returned "with a suitable media type for a JSON Schema resource" rather than explicitly showing
A The drawback is the one that @darrelmiller noted, which is that it makes what we call fragmentary documents (anything other than an OpenAPI Object at the root, or a standalone JSON Schema) more legitimate. A possible middle ground could be some other media type or media type parameter to indicate ambiguous OpenAPI content. This might be preferred, because it would correctly express that such usage is not always interoperable, which would be a great outcome. So perhaps:
|
| but they should be aware that | ||
| the server might only be able to provide a more generic media type | ||
| or a different media type according to {{Section 12.1 of HTTP}}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This interoperability considerations is warning client implementers that:
- servers (e.g., github.com) are not required to implement content negotiation;
- if a client wants to interoperate with such a server, it needs to take into account that behavior.
See https://github.com/ietf-wg-httpapi/mediatypes/pull/132/changes#r2617236017
If the wording is not clear, feel free to improve it.
|
Hi @handrews and @karenetheridge, and thanks again for all your time :) Karen> it is not unambiguously obvious which type of document needs to be requested This is exactly the point, thanks @karenetheridge. Henry> Sometimes you know what to ask for, down to the Object type, but sometimes you don't. I think that Henry> how do you know what you've gotten back OK. Henry> I most want to avoid explicitly advising people to send back application/yaml when any other media type could possibly be relevant. While I think the PR does not advise to send back application/yaml, Henry> [..the response..] comes back as Content-Type: application/schema+json github/gitlab always returns Henry> ...The document has neither an OpenAPI Object nor a JSON Schema at the root... A User Agent cannot always know from the Content-Type. A client that decides not to process a We thus need to warn implementers that - even if that's not something we endorse - this is what actually happens in the web in case they need to interoperate Henry> ... component parameter ... I'm not against a HTH + ☮️ |
|
After thinking on this, I came to a few conclusions:
So I am going to unblock this effort by bowing out. I do not have the mental or emotional energy to sort through all of my frustrations and burn-out (which are very much my problems and not yours), and I don't think we're trying to reach the same goals anyway. |
This PR