vernou
vernou

Reputation: 7590

SwaggerUIBundle : Specify base url

I need to test a api where :

API Url http://api.mydomain.loc:20109/v1/
API Definition URL http://api.mydomain.loc:20109/v1/swagger/swagger.json

The API definition is :

{
  "openapi": "3.0.1",
  "info": {
    "title": "***",
    "description": "***",
    "version": "v1"
  },
  "servers": [
    {
      "url": "/v1/path1/path2"
    }
  ],
  "/ressource1": {
      "get": {
        "responses": {
          "200": {
            "description": "Success"
          }
        }
      }
    },
  ...
}

I follow this part unpkg in the documentation to start a local Swagger UI. I create the file "swagger-ui.html" with this content :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta
    name="description"
    content="SwaggerIU"
  />
  <title>SwaggerUI</title>
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/[email protected]/swagger-ui-bundle.js" crossorigin></script>
<script>
  window.onload = () => {
    window.ui = SwaggerUIBundle({
      url: 'http://api.mydomain.loc:20109/v1/swagger/swagger.json',
      dom_id: '#swagger-ui',
    });
  };
</script>
</body>
</html>

When I open the page, the API definition is correctly loaded and Swagger UI displayed. But when I try out the endpoint "ressource1", Swagger UI call "http://api.mydomain.loc:20109/v1/path1/path2/ressource1". In my case, I want to call "http://api.mydomain.loc:20109/v1/ressource1".

How override the base path in Swagger UI with unpkg?

Upvotes: 3

Views: 6068

Answers (2)

vernou
vernou

Reputation: 7590

Swagger UI has the parameter spec :

spec : A JavaScript object describing the OpenAPI definition. When used, the url parameter will not be parsed. This is useful for testing manually-generated definitions without hosting them.

The solution is to load manually the api definition, edit the definition and pass the edited definition to Swagger UI.

Example for json OpenApi Specification :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta
    name="description"
    content="SwaggerIU"
  />
  <title>SwaggerUI</title>
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/[email protected]/swagger-ui-bundle.js" crossorigin></script>
<script>
  const swaggerUrl = "http://api.mydomain.loc:20109/v1/swagger/swagger.json"
  const apiUrl = "http://api.mydomain.loc:20109/v1/"
  window.onload = () => {
    let swaggerJson = fetch(swaggerUrl).then(r => r.json().then(j => {

      j.servers[0].url = apiUrl;
      window.ui = SwaggerUIBundle({
        spec: j,
        dom_id: '#swagger-ui',
      });
    }));
  };
</script>
</body>
</html>

Example for yaml OpenApi Specification :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta
    name="description"
    content="SwaggerIU"
  />
  <title>SwaggerUI</title>
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/[email protected]/swagger-ui-bundle.js" crossorigin></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.js" crossorigin></script>
<script>
  const swaggerUrl = "http://api.mydomain.loc:20109/v1/swagger/swagger.yaml"
  const apiUrl = "http://api.mydomain.loc:20109/v1/"
  window.onload = () => {
    let swaggerJson = fetch(swaggerUrl).then(r => r.text().then(t => {
      let j = jsyaml.load(t);
      j.servers[0].url = apiUrl;
      window.ui = SwaggerUIBundle({
        spec: j,
        dom_id: '#swagger-ui',
      });
    }));
  };
</script>
</body>
</html>

You can copy this code and just edit the value in swaggerUrl and apiUrl.

Upvotes: 3

Helen
Helen

Reputation: 97540

Here's another solution that uses a plugin with rootInjects. The main idea is the same as in @vernou's answer - update the OpenAPI definition dynamically.

<!-- index.html -->

<script>
const UrlMutatorPlugin = (system) => ({
  rootInjects: {
    setServer: (server) => {
      const jsonSpec = system.getState().toJSON().spec.json;
      const servers = [{url: server}];
      const newJsonSpec = Object.assign({}, jsonSpec, { servers });

      return system.specActions.updateJsonSpec(newJsonSpec);
    }
  }
});

window.onload = function() {
  const ui = SwaggerUIBundle({
    url: "http://api.mydomain.loc:20109/v1/swagger/swagger.json",
    ...

    // Add UrlMutatorPlugin to the plugins list
    plugins: [
      SwaggerUIBundle.plugins.DownloadUrl,
      UrlMutatorPlugin
    ],

    // This will set appropriate data when Swagger UI is ready
    onComplete: () => {
      window.ui.setServer("http://api.mydomain.loc:20109/v1")
    } 
  });

  window.ui = ui;
};
</script>

Upvotes: 6

Related Questions