Skip to content

v3.2: $self field (Alternative Approach) #4556

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

Open
wants to merge 5 commits into
base: v3.2-dev
Choose a base branch
from

Conversation

handrews
Copy link
Member

@handrews handrews commented Apr 29, 2025

This is an alternative to PR #4389. The only functional difference is that $self is required to be absolute (a change that @karenetheridge and @mikekistler are debating).

The main difference is that I drastically reduced the normative specification text and instead gave examples of all of the different ways to establish a base URI. [EDIT: and put the examples in an appendix] This is probably more understandable than trying to explain the options in prose.

@notEthan I also dumped a lot of the use cases as I think I figured out a more concise way to get the point across.

This adds $self as a way for a document to define its own URI for use in reference targets, and as the base URI for relative URI references in the document.

This does not impact the resolution of relative API URLs.

  • schema changes are included in this pull request
  • schema changes are needed for this pull request but not done yet
  • no schema changes are needed for this pull request

This adds `$self` as a way for a document to define its own URI
for use in reference targets, and as the base URI for relative URI
references in the document.

This does not impact the resolution of relative API URLs.
@handrews handrews added the re-use: ref/id resolution how $ref, operationId, or anything else is resolved label Apr 29, 2025
@handrews handrews added this to the v3.2.0 milestone Apr 29, 2025
@handrews handrews requested review from a team as code owners April 29, 2025 04:17
@handrews
Copy link
Member Author

handrews commented Apr 30, 2025

After staring at the giant examples section a lot, I decided it works better as an appendix. (force push is just because I accidentally picked up a stray file in the commit and had to edit it to pull that out).

Including fixing a bug in one of the URIs.
@lornajane
Copy link
Contributor

This is the most readable of the lot, and I think I "get" the whole thing a lot more now. Thank you for doing this work and all the iterations!

Minor points/suggestions from me (I'm not ready to approve but I've only got small questions):

  • in the proposal we called it self but it looks like now it is $self. We have other URI fields with plain-text names, why does this one need the $? Since it's being added at the top level, we can be confident of not having name clashes. (why isn't it in info with the other document information like license? Am I asking too many questions?)
  • I'd like to propose we move the appendix to the learn site and link to it. Is the learn site really good/mature/stable enough to link to from a spec file? I think it is, and the information would be better there (but needs to be very well signposted since we haven't done this for other content).

@lornajane
Copy link
Contributor

Good discussion in the meeting:

  • content does need to go to the learn site, but we're not going to block this change for it
  • $self makes sense because it's like $ref in being "special" and related to how references work

@karenetheridge
Copy link
Member

I am in agreement with the shuffling of the examples to the learn site rather than in the main spec, but not with the change from relative to absolute uri.

@mikeschinkel
Copy link

@handrews — A big +1 from me for including examples in the spec. I would prefer them to be in-line so a reader does not have to jump around to follow them, but if those examples need to be in an appendix that is better than not having any or having a link to someplace that might eventually 404.

My biggest pet peeve about specs in general is that they do not include examples which make most specs all-but-inaccessible to those like me who need examples to understand the prose.

P.S. Moving to the learn site only works IMO if there is a guarantee that the learn site will never change those examples nor take them down which, I believe, is impossible to guarantee. FTW.

@ralfhandl
Copy link
Contributor

Relative vs. absolute $self doesn't seem to make much of a difference.

  • A relative $ref is now relative to the retrieval URL. Making it relative to a relative $self which is itself relative to the retrieval URL only adds the convenience of making the $ref value shorter. It does not add a feature.

  • A relative $ref that is relative to an absolute $self also only adds the convenience of making the $ref value shorter (and relative instead of absolute). It does not add a feature.

Seems the only feature added by $self is an in-document identifier for an OpenAPI description, and that feature seems to benefit from an absolute URI value.

What am I missing?

Copy link
Contributor

@mikekistler mikekistler left a comment

Choose a reason for hiding this comment

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

I think there may be some errors in the examples of URI resolution in Appendix G. I pointed out two and I think the rest should probably be checked for accuracy before we merge this.


In this example, the retrieval URIs are irrelevant because both documents define `$self`.

For the relative `$ref` in the first document, it is resolved against `$self` to produce `https://example.com/shared/foo#/components/requestBodies/Foo`.
Copy link
Contributor

Choose a reason for hiding this comment

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

This did not look right to me, but I am far from an expert on URI resolution, so I had GitHub Copilot create a Jupyter notebook to implement the URI resolution logic in RFC 3986 Section 5.2. According to this program, the target URI is actually "https://example.com/api/shared#/components/requestBodies/Foo".

Here's a link to the code if you want to have a look.

https://github.com/mikekistler/UriResolution

The notebook includes 42 tests that it extracted from the RFC and these all pass, I have some confidence that it is working correctly.

src/oas.md Outdated
For the relative `$ref` in the first document, it is resolved against `$self` to produce `https://example.com/shared/foo#/components/requestBodies/Foo`.
The portion of that URI before the '#' matches the `$self` of the second document, so the reference target is resolved to `#/components/requestBodies/Foo` in that second document.

In that document, the `$ref` in the Request Body Object is resolved using that document's `$self` as the base URI, producing `https://example.com/schemas/foo`.
Copy link
Contributor

Choose a reason for hiding this comment

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

This too does not jive with the resolver that Copilot built. It says that the target URI is actually "https://example.com/api/schemas/foo".

Copy link
Member Author

Choose a reason for hiding this comment

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

@mikekistler should be fixed. Really, "these look wrong" would have been sufficient here. The errors were just because I reworked the various paths at some point to make the examles cover more cases, and some things didn't get updated post-rework. Nothing obscure was going on.

Although it sounds like you produced something useful beyond this which is cool!

Never change your directory structure halfway through
writing examples...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
re-use: ref/id resolution how $ref, operationId, or anything else is resolved
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants