Only the final defined document is instantiated by the Swagger-ui-express module

Currently, I am working on a Typescripted nodejs server and facing an issue with defining different swagger paths for separated controllers. The problem is that the swagger-ui-express module only displays the last defined document in the specific route.

In my index.ts file for group X of controllers:

import express from 'express';
import passport from 'passport';
const router = express.Router();
// Import all bot routes
import { authRoute } from './auth';
import { botCrudRoute } from './bot-crud';
import { aiRoutes } from './ai';
import { categoryCrudRoute } from './categories-crud';

const swaggerUi = require('swagger-ui-express');
import { botSwaggerDoc } from './swagger';

const swaggerDoc = botSwaggerDoc;

const swaggerUiOpts = {
    explorer: false
};

// Swagger setup
router.use('/api-docs', swaggerUi.serve);
router.get('/api-docs', swaggerUi.setup(swaggerDoc, swaggerUiOpts));

In my index.ts file for group Y of controllers:

import express from 'express';
const router = express.Router();
// Import all bot routes

const swaggerUi = require('swagger-ui-express');
import { adminSwaggerDoc } from './swagger';

const swaggerDoc = adminSwaggerDoc;

const swaggerUiOpts = {
    explorer: false
};

// Swagger setup
router.use('/api-docs', swaggerUi.serve);
router.get('/api-docs', swaggerUi.setup(swaggerDoc, swaggerUiOpts));

export const adminRoutes = router;

My api.ts file groups all controllers together:

'use strict';

import express from 'express';
import { Response, Request, NextFunction } from 'express';
import { adminRoutes } from './admin';
import { botRoutes } from './bot';
// import { onboardRoutes } from './onboard';

const router = express.Router();

// router.use('/onboard', onboardRoutes);
router.use('/bot', botRoutes);
router.use('/admin', adminRoutes);

export const apiRoutes = router;

In server.ts:

/**
 * Primary app routes.
 */
app.use('/api', apiRoutes);

An example snippet of one of the swaggerDocs:

export const botSwaggerDoc = {
    'swagger': '2.0',
    'info': {
        'version': '1.0.0',
        'title': 'Cupo embed chat bot API',
        'license': {
            'name': 'Internal use only'
        }

The issue lies in the fact that the swagger-ui-express module seems to only use the last defined document, almost as if the server retains reference to that particular document...

Answer №1

To overcome this issue, I found a solution by directly serving the HTML for each individual API. Here's how I did it:

// Index.ts for group X of controllers

  const apiV1Html = swaggerUi.generateHTML(
    v1SwaggerDocument,
  );
  router.use(
    '/docs',
    swaggerUi.serveFiles(v1SwaggerDocument),
  );
  router.get('/docs', (req: any, res: any) => {
    res.send(apiV1Html);
  });
  
  

And for group Y of controllers:

// Index.ts for group Y of controllers

  const apiV2Html = swaggerUi.generateHTML(
    v2SwaggerDocument,
  );
  router.use(
    '/docs',
    swaggerUi.serveFiles(v2SwaggerDocument),
  );
  router.get('/docs', (req: any, res: any) => {
    res.send(apiV2Html);
  });
  
  

Sources: https://github.com/scottie1984/swagger-ui-express/issues/65

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for encrypting a string in JavaScript?

Is there a simple way to hash a string in JavaScript without having to create the hashing algorithm myself? Are there any reliable npm packages or built-in functions available for this task? If so, how can I utilize them to hash a string? For instance, if ...

The integration of Next.js with a Custom Express Server results in incorrect content types being generated for woff and woff2 files

I recently migrated my Next.js app to a new dedicated cpu server on Digital Ocean, and now I'm facing an issue where my fonts are being served with Content-Type: text/html; charset=utf-8, resulting in a 500 error. Strangely enough, this was not a prob ...

Arranging information within the Ngb-Accordion

Welcome to the code snippet showcasing how to create an accordion in Angular: <ngb-accordion [closeOthers]="false" activeIds="0"> <ng-container class="card" *ngFor="let post of Posts"> <ngb-panel title="{{post.title}} - ...

When running fs.rmSync on Ubuntu, an error is thrown stating that undefined is not a

Attempting to remove a basic folder that contains another nested folder, such as: /tmp/ac6c1fcaeae0c7ec4d1a8/res. Here is the code I am using: module.exports.deleteFolder = (path) => { try { if (fs.existsSync(path)) { console.lo ...

The array initially provides accurate values, however, upon subsequent calls, it inexplicably returns all values as "undefined"

After successfully reading a bunch of JSON files and storing them into an array, I encountered a strange issue. When I console logged the array initially, all the values were correct. However, upon rendering a page and logging the array again, all values ...

Can you explain the purpose of node-libs-browser and the reason it is included in the installation process of babel-loader?

Recently, I added babel loader to my webpack setup by installing it from GitHub. After installation, I noticed that it introduced 3 new node dependencies. Surprisingly, only 2 of these were mentioned in the babel loader package.json "peerDependencies": { ...

The middleware is causing disruptions in the configuration of redis and express

I've recently started using Redis and I'm facing an issue with my middleware 'cache' function that seems to be causing problems in my code. Everything works fine without it, the data displays correctly in the browser, and when I check f ...

What steps can be taken to ensure express Node.JS replies to a request efficiently during periods of high workload

I am currently developing a Node.js web processor that takes approximately 1 minute to process. I make a POST request to my server and then retrieve the status using a GET request. Here is a simplified version of my code: // Setting up Express const app = ...

IPv6 with Socket.IO (Updated January 2013)

I am in need of utilizing Socket.IO and its client to establish a connection between two Node.js servers via an IPv6 network. It was mentioned one year back that this could not be done due to address parsing issues with the client. However, it seems that ...

Having trouble closing my toggle and experiencing issues with the transition not functioning properly

Within my Next.js project, I have successfully implemented a custom hook and component. The functionality works smoothly as each section opens independently without interfering with others, which is great. However, there are two issues that I am facing. Fi ...

AngularJS - Unusual outcomes observed while utilizing $watch on a variable from an external AngularJS service

Within the constructor of my controllers, I execute the following function: constructor(private $scope, private $log : ng.ILogService, private lobbyStorage, private socketService) { this.init(); } private init(){ this.lobbyData = []; this.initial ...

Parent route being called by express route once more

One of my express routes in router/blog.js looks like this: in router/blog.js router.get('/', middleware.isLoggedIn, function(req,res){ //some code res.render('blogs'); }) After that, I have another route for adding new blogs: route ...

Is there a way to allow an HTML page rendered by node.js to communicate back to its corresponding node.js file?

I am currently in the process of developing a registry system using node.js and HTML. However, I have encountered an issue where my HTML page is rendered by node.js, but when trying to call it back to the node.js file, it appears that the JS file cannot be ...

The border of the Material UI Toggle Button is not appearing

There seems to be an issue with the left border not appearing in the toggle bar below that I created using MuiToggleButton. Any idea what could be causing this? Thank you in advance. view image here view image here Just a note: it works correctly in the ...

Storing client time data in a database using Node.js

Just starting out with Node.js so bear with me while I learn the ropes. I successfully set up a basic TCP server using the guide here In my current project, users will connect to the server from a web browser and I'm interested in capturing the TCP ...

When using Node.js, the rendering of the ejs file does not function properly until the directory name is updated from "view" to "views"

After encountering a persistent status code 500 error on every request when trying to access the profile.ejs file saved in the view folder, a simple solution was discovered. By renaming the folder from 'view' to 'views', everything sudd ...

Unexpected behavior with Node js event listener

I am currently working on emitting and listening to specific events on different typescript classes. The first event is being listened to properly on the other class, but when I try to emit another event after a timeout of 10 seconds, it seems like the lis ...

`How to Merge Angular Route Parameters?`

In the Angular Material Docs application, path parameters are combined in the following manner: // Combine params from all of the path into a single object. this.params = combineLatest( this._route.pathFromRoot.map(route => route.params) ...

Maintaining accurate type-hinting with Typescript's external modules

Before I ask my question, I want to mention that I am utilizing Intellij IDEA. In reference to this inquiry: How do you prevent naming conflicts when external typescript modules do not have a module name? Imagine I have two Rectangle classes in different ...

Changing the structure of a JSON array in JavaScript

I'm currently developing an ExpressJS application and I need to send a post request to a URL. My data is being retrieved from a MS SQL database table using Sequelize, and the format looks like this: [ { "x":"data1", "y":& ...