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

Normalize relative ref paths to avoid duplicating schemas #2105

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

ctreatma
Copy link

@ctreatma ctreatma commented Jun 17, 2024

Currently, if an OpenAPI spec contains multiple relative refs to the same file, but those refs are located in different files and use different relative paths to reach the one file, swagger-parser will create a separate, duplicate schema for each relative path rather than reusing the same schema across all equivalent paths.

For example, given a spec with the following refs:

  • In spec root directory, $ref: ./components/schemas/Thing.yaml
  • In components/paths subdirectory, $ref: ../../components/schemas/Thing.yaml

The parser will produce a Thing and a Thing_1 schema object instead of reusing Thing for the second, equivalent reference.

This updates the ref processor to resolve relative paths before processing relative refs in order to produce a single Thing schema that is reused for all equivalent references.

Fixes #2016, fixes #1518, and maybe others.

@ctreatma ctreatma force-pushed the collapse-equivalent-refs branch from 6f1d634 to 18d5450 Compare June 17, 2024 15:10
@nmarriotti
Copy link

Just ran into this issue today. Glad to see a fix is on the way (hopefully soon). Thanks!

@ctreatma ctreatma force-pushed the collapse-equivalent-refs branch 2 times, most recently from d25dc19 to e2fd955 Compare August 8, 2024 20:11
@ctreatma ctreatma force-pushed the collapse-equivalent-refs branch from e2fd955 to 8174b8f Compare December 20, 2024 17:08
@ctreatma
Copy link
Author

I rebased on the latest from master to confirm that the issue described in this PR still exists and that the changes in this PR are sufficient to resolve it.

@ctreatma ctreatma force-pushed the collapse-equivalent-refs branch from 8174b8f to 47a4931 Compare January 8, 2025 16:35
@ctreatma ctreatma force-pushed the collapse-equivalent-refs branch from 47a4931 to 26e34ae Compare January 8, 2025 17:18
@@ -92,6 +93,20 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) {
return renamedRef;
}

RefFormat format = computeRefFormat($ref);
if (format.equals(RefFormat.RELATIVE)) {
String normalizedRef = "./" + Paths.get($ref).normalize().toString();
Copy link
Author

Choose a reason for hiding this comment

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

To minimize impact on existing tests, this normalizes with a leading ./. It might be preferable to leave that out in normalized paths, but that would require changes to a number of tests that currently explicitly check for paths starting with ./.

Copy link
Author

Choose a reason for hiding this comment

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

It looks like this matches existing behavior so should be OK as-is; the deserializer adds a leading ./ to relative references.

Given the existing behavior, an alternative approach to fixing this path resolution issue might be to normalize the relative path in mungeRef instead, although I'm not clear if that change would have to happen in only one or in both of OpenAPIDeserializer.mungeRef and RefUtils.mungeRef.

Copy link
Author

Choose a reason for hiding this comment

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

Update to use RefUtils.mungeRef; I tried moving the path normalization elsewhere and it didn't work, so that approach will need more investigation (for me, at least).

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