22

I saw in the swagger ui documentation that you can provide a urls parameter which is:

An array of API definition objects ({url: "", name: ""}) used by Topbar plugin. When used and Topbar plugin is enabled, the url parameter will not be parsed. Names and URLs must be unique among all items in this array, since they're used as identifiers.

I was hoping that this will give me a selector from which I can chose which of my yaml files to process. Unfortunately, it doesn't seem to do anything.

Here is my code:

window.onload = function() {
  // Build a system
  const ui = SwaggerUIBundle({
    urls: [
      {
        url: "http://test.dev/documentation/microservices/microservices.yaml",
        name: "All Microservices"
      },
      {
        url: "http://test.dev/documentation/microservices/plans.yaml",
        name: "Plans"
      },
    ],
    dom_id: '#swagger-ui',
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIStandalonePreset
    ],
    plugins: [
      SwaggerUIBundle.plugins.DownloadUrl
    ],
    layout: "StandaloneLayout"
  })

  window.ui = ui
}

I'd also like to set the primaryName to All Microservices.

Any ideas on where I'm going wrong?

gnupa
  • 65
  • 9
zag2010
  • 439
  • 2
  • 4
  • 10

2 Answers2

32

The urls configuration option is supported in Swagger UI 3.0.18 and later.

You can use it instead of url like this:

window.onload = function() {
  // Build a system
  const ui = SwaggerUIBundle({
    urls: [
      {url: "https://path/to/api1.yaml", name: "API One"},
      {url: "https://path/to/api2.yaml", name: "API Two"},
    ],
    "urls.primaryName": "API Two"  // default document (if other than the first)
    ...
  })

Result:

"Select a definition" dropdown in Swagger UI

Helen
  • 87,344
  • 17
  • 243
  • 314
  • Thanks Helen, I didn't realise this was a new feature. – zag2010 Jun 29 '17 at 12:31
  • 1
    Multiple URLs can also be used with the `swaggerapi/swagger-ui` Docker container with an `environment` like this: `URLS=[{ url: 'api1.yaml', name: 'API One' }, { url: 'api2.yaml', name: 'API Two' }]` – sdm4n Feb 28 '22 at 11:31
2

If the above solution works for you, great! But based on my own experience and research, it's not so simple for a lot of us.

The Swagger UI Documentation seems to suggest the urls parameter will do exactly what we're all looking for, but there's a little caveat: "used by Topbar plugin". What's the "Topbar plugin?" This is, in fact, the only mention of such a plugin in the entire documentation!

Burrowing deeper into the rabbit hole, one might discover as I did that this is a part of the "Standalone Layout." This led me to the discovery of the SwaggerUIBundle object, which is part of the swagger-ui-dist module, which is somehow different from the swagger-ui module, and yet really, really similar. Am I crazy, or is this all insanely convoluted?

For those who would rather stop digging deeper down the rabbit hole, I began digging into the source code instead and eventually uncovered the undocumented features which allow us to do exactly what we need - swap out the swagger yaml file used by the UI rendering. It's actually so simple, once you know what to do:

const ui = SwaggerUI({
    url: 'https://example.com/swagger-v1.yaml',
    dom_id: '#swaggerDocs'
});

ui.specActions.updateUrl('https://example.com/swagger-v2.yaml');
ui.specActions.download('https://example.com/swagger-v2.yaml');

With these methods at your disposal, you can build any UI you'd like to give your users the ability to browse through different swagger definitions.

Aaron Lozier
  • 290
  • 1
  • 4
  • 13