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

Resolving OpenAPI References in Swagger Editor #5204

Open
BrunoPBenedetti opened this issue Jul 25, 2024 · 1 comment
Open

Resolving OpenAPI References in Swagger Editor #5204

BrunoPBenedetti opened this issue Jul 25, 2024 · 1 comment

Comments

@BrunoPBenedetti
Copy link

I encountered an issue with resolving references in Swagger Editor, as described in this issue. To address this, I wrote a simple TypeScript function that resolves $ref references in OpenAPI YAML files. Here’s the solution:

/* eslint-disable @typescript-eslint/no-explicit-any */
import fs from 'fs';
import path from 'path';
import YAML from 'yaml';

export function resolveOpenApiReferences(basePath: string, nameYaml: string) {
  const resolveReferences = (obj: any, dir: string) => {
    for (const key in obj) {
      if (typeof obj[key] === 'object') {
        resolveReferences(obj[key], dir);
      } else if (key === '$ref' && !obj[key].startsWith('#')) {
        const refPath = path.resolve(dir, obj[key]);
        const fileContent = fs.readFileSync(refPath, 'utf8');
        const fileData = YAML.parse(fileContent);
        Object.assign(obj, fileData);
        delete obj[key];
        resolveReferences(obj, path.dirname(refPath)); // Resolve nested $ref
      }
    }
  };

  const fileContent = fs.readFileSync(path.resolve(basePath, nameYaml), 'utf8');
  const swaggerDocument = YAML.parse(fileContent);

  resolveReferences(swaggerDocument, basePath);

  return swaggerDocument;
}

Explanation
This function, resolveOpenApiReferences, recursively resolves $ref references in an OpenAPI YAML document. Here's a brief overview of how it works:

Reading the YAML File: The function reads the main OpenAPI YAML file from the specified base path.
Parsing YAML: It parses the file content into a JavaScript object using the yaml package.
Resolving References: The nested resolveReferences function iterates through the object and looks for $ref keys that do not start with # (indicating internal references). When it finds such a reference, it reads the referenced file, parses its content, and replaces the $ref key with the actual data from the referenced file. This process is repeated recursively to handle nested references.
This approach ensures that all external references in your OpenAPI document are resolved correctly, making it easier to work with Swagger Editor.

Usage with Express
You can integrate this function with an Express application to serve your OpenAPI documentation. Here's an example of how to do it:

import express from 'express';
import swaggerUi from 'swagger-ui-express';
import { resolveOpenApiReferences } from './path/to/your/resolveOpenApiReferences';

const app = express();
const swaggerDocument = resolveOpenApiReferences('./swagger/', 'openapi.yaml');

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

In this example, the resolveOpenApiReferences function is used to load and resolve the OpenAPI document before setting up the Swagger UI middleware in an Express application. This allows you to serve your fully resolved OpenAPI documentation at the /api-docs endpoint.

Feel free to use and modify this function to fit your needs!

@zba
Copy link

zba commented Jul 26, 2024

I think you need also to check if there is no protocol scheme in ref url, like && !obj[key].match(/^[^/:]+:\/{2}|^#/

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

No branches or pull requests

2 participants