Skip to content
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

Support reference objects in operation parameters #1749

Closed
wants to merge 5 commits into from

Conversation

richvdh
Copy link
Member

@richvdh richvdh commented Mar 13, 2024

According to https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#operation-object, the entries in parameters lists can be reference objects. We don't currently support that in our templates, so let's fix that.

Preview: https://pr1749--matrix-spec-previews.netlify.app


Handles OpenAPI "Reference Objects".

Reference objects are JSON objects with a single property, `$ref` (and
Copy link
Contributor

@zecakeh zecakeh Mar 13, 2024

Choose a reason for hiding this comment

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

It's actually a bit more complicated than that… Depending on the property it is used in, the behavior of conflicts could be undefined.

This table summarizes things.

Copy link
Member Author

Choose a reason for hiding this comment

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

Right. I guess we are specifically targetting "reference objects" here, so it's correct that summary and description are preserved?

I guess we'd need to make this logic more generic if we wanted to use it in other places, but that could be a future change.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, what made me react here is more the comment in the resolve-refs partial that says it should be replaced by this one, but in its current state it's not possible.

Copy link
Member Author

Choose a reason for hiding this comment

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

ah ok, maybe we can clarify that comment.

Comment on lines +57 to +66
{{/*
OpenAPI spec says that "summary" and "description" from the reference object override
the values from the referenced component.
*/}}
{{ if isset $schema "summary" }}
{{ $ret = merge $ret (dict "summary" $schema.summary) }}
{{ end }}
{{ if isset $schema "description" }}
{{ $ret = merge $ret (dict "description" $schema.summary) }}
{{ end }}
Copy link
Contributor

Choose a reason for hiding this comment

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

If we want to be more strict with how we resolve refs, should we throw an error or log a warning if $schema and $ret have properties of the same name, other than those? That would allow to know sooner what is wrong if someone expects the ref to be overwritten by the schema, which we often do, but requires the use of allOf.

"parameters" $parameters
"type" "header"
"caption" "header parameters"
"path" $path
Copy link
Contributor

Choose a reason for hiding this comment

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

path is expected to be the path to the file, but the one received by this partial is the path to the folder containing the file. So we need to have the filename in the path here somehow, without interfering with other partials that use resolve-refs and still expect the folder.

@@ -0,0 +1,69 @@
{{/*
Copy link
Contributor

Choose a reason for hiding this comment

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

We also need to update scripts/check-openapi-sources.py to support this, as it only resolves refs inside JSON schemas.

@zecakeh
Copy link
Contributor

zecakeh commented Mar 14, 2024

For the refactoring I made in #1751, we will also need to support reference objects in the Responses Object, and the Media Type Object for examples.

I don't know if we should add support for those here or in another PR.

@richvdh
Copy link
Member Author

richvdh commented Mar 18, 2024

Having discussed this again with @zecakeh:

As things currently stand, we implement $ref by calling resolve-refs, which recursively expands $ref without concern about where the $ref actually is. The problem with that is then it's unclear whose job it is to call resolve-refs. I was hoping to resolve that by moving towards a model where we only expand $ref in places where we know it is valid. But I'm now wondering if that is actually worthwhile.

Instead, maybe we should just call resolve-refs in the top-level template (layouts/shortcodes/http-api.html, etc), and rely on the validator to actually enforce the rules. This is also what happens in scripts/dump-openapi.py.

It's also worth noting that we currently use $ref in a place where OpenAPI doesn't permit it (in the bodies of examples), and, assuming we want to keep that power (I think we do) we probably need the recursive resolve-refs for that.

So, I'm going to abandon this approach, in favour of @zecakeh's solution over at #1751.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants