scottie1984 / swagger-ui-express

Adds middleware to your express app to serve the Swagger UI bound to your Swagger document. This acts as living documentation for your API hosted from within your app.
MIT License
1.43k stars 228 forks source link

Multiple API specs loaded from URLs at separate routes do not work #305

Closed richiksc closed 2 years ago

richiksc commented 2 years ago

If I try to have two routes that serve from SwaggerUI express that each load from separate OpenAPI spec URLs, the same API spec and spec URL is shown for both routes:

const swaggerUiOptsA = {
    swaggerOptions: { url: '/path/to/specA' }
}

const swaggerUiOptsB = {
    swaggerOptions: { url: '/path/to/specB' }
}

router.use('/', swaggerUi.serveFiles(null, swaggerUiOptsA));
router.get('/', swaggerUi.setup(null, swaggerUiOptsA));

router.use('/service-b', swaggerUi.serveFiles(null, swaggerUiOptsB));
router.get('/service-b', swaggerUi.setup(null, swaggerUiOptsB));

Then, accessing both / and /service-b displays the docs rendered from /path/to/specA and display /path/to/specA as the OpenAPI spec URL on the page.

This behavior works if I pass in an actual JSON object as the swaggerDocument parameter for each of them, but for my use case, I need the specs loaded from the URLs.

danielnmai commented 2 years ago

I ran into this issue as well, swagger UI always show the last spec file, even there are 2 different files and they're in different routes. There is a workaround I came up with: using the explorer dropdown to select the spec file you want. It still has 1 single route, so not sure it would fit your solution. Here's the code:

app.get('/api-docs/specA.json', (req, res) => res.json(specA));
app.get('/api-docs/specB.json', (req, res) => res.json(specB));

  const options = {
    explorer: true,
    swaggerOptions: {
      urls: [
        {
          url: '/api-docs/specA.json',
          name: 'Spec A',
        },
        {
          url: '/api-docs/specB.json',
          name: 'Spec B',
        },
      ],
    },
  };

app.use('/v1/api-docs', swaggerUI.serve, swaggerUI.setup(undefined, options));

This loads the json files dynamically by setting the routes internally, but if you have public external URLs, it should work as well.

ronaldl29 commented 1 year ago

I'm running into the same issue as well. Thank you @danielnmai for the workaround. However, is there a way to do this with 2 different URLs (without the explorer dropdown?)

talha-ah commented 1 year ago

I found a solution to 2 different URLs here: https://github.com/scottie1984/swagger-ui-express/issues/353#issuecomment-1764242581