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

Prevent redocly bundle from creating new schema objects in #/components/schemas when using --dereferenced option #1798

Open
outdooracorn opened this issue Nov 8, 2024 · 5 comments

Comments

@outdooracorn
Copy link

Describe the bug

The redocly bundle command is adding schema objects to the #/components/schemas section of the bundled schema, even when using the --dereferenced option is used.

Closed issue #239 seems to be similar and points to using the --dereferenced option to solve this issue.

To Reproduce
Steps to reproduce the behavior:

  1. Given this redocly.yaml file
  2. And these OpenAPI files
  3. Run npx redocly bundle schema/openapi.json --dereferenced -o out/openapi.json
  4. See that PropertyValuePair and Error schema objects are added to #/components/schemas in the bundled OpenAPI document

Expected behavior

I would expect only (dereferenced versions of) the schema objects present in schemas.json to be in the #/components/schemas section of the bundled and dereference OpenAPI document.

Logs

OpenAPI description

OpenAPI v3.1 - see example repo

Redocly Version(s)

"@redocly/cli": "^1.25.11",

Node.js Version(s)

v18.20.4 and v20.12.2

OS, environment

Kubuntu 22.04

Additional context

@outdooracorn outdooracorn added the Type: Bug Something isn't working label Nov 8, 2024
@tatomyr
Copy link
Contributor

tatomyr commented Nov 12, 2024

Have you tried using the --remove-unused-components option?

@outdooracorn
Copy link
Author

outdooracorn commented Nov 12, 2024

Have you tried using the --remove-unused-components option?

I have. It removes some, but not all, of the components. In this example, #/components/schemas/Statement is left.

I also don't want to remove all the components. I would like to keep #/components/schema so that it displays the schemas section in Swagger UI.

@tatomyr
Copy link
Contributor

tatomyr commented Nov 13, 2024

Ah, so you want to bundle your files, preserve the existing components, and not add the new ones? Then it's more of an enhancement rather than a bug. I'm not sure it would be an easy change. It will require modifying the internals, as the bundler currently resolves external references into the components section regardless of the --dereferenced option because the component might be used in an indirect way (e.g. in a discriminator).
However, you can try using a custom plugin with a decorator to filter schemas that were only present in the original components. It should probably look like this:

const filterSchemas = () => {
  let originalSchemas;
  return {
    Components: {
      leave(components) {
        for (const key in components.schemas || {}) {
          if (originalSchemas?.[key] === undefined) {
            delete components.schemas[key];
          }
        }
      },
      NamedSchemas: {
        enter(schemas) {
          originalSchemas = schemas;
        },
      },
    },
  };
};

Please let me know if that works!

@tatomyr tatomyr added Type: Enhancement and removed Type: Bug Something isn't working labels Nov 13, 2024
@outdooracorn
Copy link
Author

Ideally, we would like to bundle the files and only dereference/inline schemas that aren't already in #/components. Said differently, keep references to components already in #/components, and dereference/inline everything else.

Thanks for the custom decorator plugin code, we will try it out.

@gnvk
Copy link

gnvk commented Jan 22, 2025

We're currently using swagger-cli to bundle our OpenAPI specifications and we're trying to migrate to redocly. This issue seems to be a blocker for us that we can't even really work around.

I created a minimal, reproducible example to demonstrate the issue: https://github.com/gnvk/redocly_example
In this example we have 3 OAS specifications (stock, crypto, openapi). The bundled files are in the generated directory. The files bundled by swagger-cli use the schema definitions already in the original yaml, e.g. components.schemas.StockTrade, while redocly creates a new schema components.schemas.trade-2 (and also displays a warning).

We also use oapi-codegen to generate Go code from the bundled schemas. Actually this is the main reason to bundle them in the first place. The original, swagger-cli bundled files have nice schema tags that yield meaningful Go structs: stock.Trade (stock package, Trade struct, generated from stock.yaml), openapi.StockTrade (openapi common package, StockTrade struct, generated from openapi.yaml). On the other hand, the redocly bundled files have these strange trade, trade-2, symbol, symbol-2schemas, which will be generated toopenapi.Trade2`.

We even tried custom decorators to work around this but without success. We'd be happy with either of these:

  1. Use the already existing schema in the original file (like swagger-cli does)
  2. We can remove those schemas, but then the generated schemas should have proper names. trade in stock.yaml but stock_trade in openapi.yaml. If the schema is unique, its name should be simply the filename, but if it's not, the directory name should be used instead of number postfixes (as recommended by this comment).

Can anyone here recommend a solution, or at least a workaround?

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

3 participants