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

$refs with relative paths are not properly resolved with async spec loading #2578

Open
anikitin opened this issue May 2, 2024 · 6 comments

Comments

@anikitin
Copy link

anikitin commented May 2, 2024

Context

Our OpenAPI files contain references to common schemas defined in separate YaML files

Current Behavior

If I have "$ref" in OpenAPI document with a relative path, it is not properly resolved.

It is actually resolved based on current HTML page address instead of OpenAPI document (that contains this $ref) address.
Browser console shows HTTP 404.

Expected Behavior

$ref with relative paths should be properly resolved based on rendered OpenAPI document address (ReDoc and Swagger UI do it properly)

Environment

I used the version from CDN https://unpkg.com/@stoplight/elements/web-components.min.js

@brendarearden
Copy link
Contributor

@anikitin please provide an example of the openAPI document that contains the relative ref, along with the file that it is referencing so that we can reproduce this issue. Could you also provide an example of the html you are using.

@anikitin
Copy link
Author

anikitin commented May 3, 2024

Sure. After experiments it seems that it only affects async loading, not the static way of specifying "apiDescriptionUrl".

This is the example of OpenAPI file I want to render: https://raw.githubusercontent.com/anikitin/static-assets/main/oas-refs/test1-openapi.yml

This is my HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
</head>

<body>

    <elements-api id="docs" router="hash" layout="sidebar" hideTryIt="true" hideExport="true" hideSchemas="true">
    </elements-api>

    <script>
        (async () => {
            const docs = document.getElementById('docs');
            const text = await fetch('https://raw.githubusercontent.com/anikitin/static-assets/main/oas-refs/test1-openapi.yml').then(res => res.text())
            docs.apiDescriptionDocument = text;
        })();
    </script>

</body>
</html>

This is what I see in browser:

image

@anikitin anikitin changed the title $refs with relative paths are not [properly resolved $refs with relative paths are not properly resolved with async spec loading May 3, 2024
@brendarearden
Copy link
Contributor

Thank you so much for providing that additional information!

Our suspicion is that the way you are getting the document is causing the issue

            const text = await fetch('https://raw.githubusercontent.com/anikitin/static-assets/main/oas-refs/test1-openapi.yml').then(res => res.text())
            docs.apiDescriptionDocument = text;

Once the test1-openapi.yml file is returned, elements has no context of how to resolve

schema:
     $ref: "test2-openapi.yml#/components/schemas/Schema2"

or

Schema1RefTo3:
     $ref: "test3-openapi.yml#/components/schemas/Schema3"

Potential workarounds:

  • Specify the full path in your refs: example - $ref: "https://raw.githubusercontent.com/anikitin/static-assets/main/oas-refs/test3-openapi.yml"
  • use an openAPI bundler to preprocess the document so when you get the text, it has all of the references already bundled into it

@anikitin
Copy link
Author

@brendarearden , workarounds are clear but unfortunately not possible for us. I still think this is a bug because:

  1. When exactly the same URL is processed via static URL it works properly
  2. Other libraries like ReDoc can handle it.

I understand that it can be related to async implementation with "fetch" method.
This example was taken from Stoplight documentation.
But then, to resolve this issue, there should be some another way to feed an OpenAPI document at runtime that preserves the path and allows handling relative links.

I wonder how Stoplight demo app handles this with dynamically loaded document: https://elements-demo.stoplight.io/

@anikitin
Copy link
Author

OK, I have figured out that I can just set apiDescriptionUrl programmatically in JS instead of doing async loading.

So this issue can be closed, but I recommend adding an example to https://docs.stoplight.io/docs/elements/a71d7fcfefcd6-elements-in-html that demonstrates how to set apiDescriptionUrl in JavaScript. It is very typical scenario where the URL is selected dynamically, and it is important to load it properly with all external $refs. Current provided examples of dynamic loading don't support it. properly.

Copy link

github-actions bot commented Jun 7, 2024

This ticket has been labeled jira. A tracking ticket in Stoplight's Jira (STOP-618) has been created.

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

No branches or pull requests

2 participants