Search code examples
swaggerswagger-ui

Change basePath for swagger-ui


I used swagger project create to stand up an API for a node service. I followed these instructions. I'm also using swagger-tools to serve the swagger-ui.

I'd like to dynamically change the basePath of the API and its documentation from '/' and '/docs' to routingPath and routingPath + '/docs'.

I am able to change the basePath of my swagger API spec, but I'm not sure how to change the basePath of the swagger-ui. My code looks like this:

'use strict';

const defaultRoutingPath = '/api/collection';
const defaultPort = 3000;

var path = require('path');
var SwaggerExpress = require('swagger-express-mw');
var SwaggerUi = require('swagger-tools/middleware/swagger-ui');
var app = require('express')();
module.exports = app; // for testing

var routingPath = process.env.ROUTING_PATH || defaultRoutingPath;

var config = {
  appRoot: __dirname // required config
};

SwaggerExpress.create(config, function(err, swaggerExpress) {
  if (err) { throw err; }

  swaggerExpress.runner.swagger.basePath = routingPath; // this works

  app.get('/', (req, res) => {
    res.redirect(path.join(routingPath, 'docs'));
  })

  // enable SwaggerUI
  app.use(swaggerExpress.runner.swaggerTools.swaggerUi({
    basePath: routingPath  // this has no effect
  }));

  // install middleware
  swaggerExpress.register(app);

  var port = process.env.PORT || defaultPort;
  app.listen(port);

  if (swaggerExpress.runner.swagger.paths['/hello']) {
    console.log('try this:\ncurl http://127.0.0.1:' + port + path.join(routingPath, '/hello?name=Scott'));
  }
});

If I run this service, I will find my API spec at http://localhost:3000/api/collection

And my docs page at http://localhost:3000/docs

I would like to serve the docs page at http://localhost:3000/api/collection/docs

I attempted to do that by passing a basePath option to the swaggerUi constructor.

  // enable SwaggerUI
  app.use(swaggerExpress.runner.swaggerTools.swaggerUi({
    basePath: routingPath  // this has no effect
  }));

That didn't work. Anyone know how to configure the basePath of the swagger-ui?


Solution

  • I figured out the answer to my question following essentially this guidance.

    The key was to add a second express app (subpath) and use a routingPath from the main app. Here's the code.

    'use strict';
        
    const defaultRoutingPath = '/api/collection';
    const defaultPort = 80;
    
    var path = require('path');
    var SwaggerExpress = require('swagger-express-mw');
    var SwaggerUi = require('swagger-tools/middleware/swagger-ui');
    var express = require('express');
    var app = express();
    var subpath = express();
    module.exports = app; // for testing
    
    var routingPath = process.env.ROUTING_PATH || defaultRoutingPath;
    
    var config = {
      appRoot: __dirname, // required config
    };
    
    SwaggerExpress.create(config, function(err, swaggerExpress) {
      if (err) { throw err; }
      
      app.use(routingPath, subpath);
      
      app.get('/', (req, res) => {
        res.redirect(path.join(routingPath, 'docs'));
      })
      
      swaggerExpress.runner.swagger.basePath = routingPath;
    
      // enable SwaggerUI
      subpath.use(swaggerExpress.runner.swaggerTools.swaggerUi());
    
      // install middleware
      swaggerExpress.register(app);
    
      var port = process.env.PORT || defaultPort;
      app.listen(port);
    
      if (swaggerExpress.runner.swagger.paths['/health']) {
        console.log('try this:\ncurl http://127.0.0.1:' + port + path.join(routingPath, '/health'));
      }
    });
    

    Now my docs are available here: http://localhost:3000/api/collection/docs/