35

I am trying to setup swagger on top of my node application using the swagger npm package. I have my end points and swagger setup perfect(atleast almost perfect), I did do quiet a lot of research on whats going wrong but I couldn't find the trace. My swagger setup file:

const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const swaggerJSDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
const abc= require('./routes/abc');
var app = express();

const swaggerDefinition = {
    info: {
        title: 'Analytics Project',
        version: '1.0.0',
        description: 'Analytics API swagger documentation'
    }
};
const options = {
    swaggerDefinition,
    apis: ['./routes/abc.js']
};

const swaggerSpec = swaggerJSDoc(options);

var api = require('./routes/abc');
app.use('/', api);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/api/v1/abc', abc);
app.use('/api/v1/abc/scatter', abc);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
module.exports = app;

My end points are defined in ./routes/abc.js:

var express = require('express');
var router = require('express').Router();
const request = require('request');

/**
 * @swagger
 * /:
 *   get:
 *     description:  Endpoint for everything
 */
router.get('/', function(req, res, next) { //End point1
    res.send('hello from dataservice');
  });

/**
 * @swagger
 * /scatter:
 *   post:
 *    description:  Endpoint for all variations of scatter plots
 */
router.post('/scatter', function(req, res, next) { //end point2
    res.json({users: [{name: 'Timmy'}]});
  });
module.exports = router;

I was expecting the 2 end points to show up on the page. But instead I get the 'No operations defined in spec!' error. What am I missing? Any help is appreciated.

Saranya Garimella
  • 465
  • 1
  • 5
  • 12

11 Answers11

29

It may be that there is an issue with how you are referencing your routes. The referencing must always start from the root of your application. So './routes/abc.js' must be changed to 'the-folder-name-in-root/routes/abc.js'

Jesse Scherer
  • 1,492
  • 9
  • 26
Wisdom
  • 291
  • 3
  • 6
  • 6
    I made changes to path starting from root folder of project but i have still same issue – Karol Nov 03 '19 at 23:14
  • 1
    Have you found a solution for this yet? – Ilo Calistus Feb 11 '20 at 13:14
  • This is what I had to do as well. In my case, the main folder was being built from `/src` therefore my path would become "src/routes/*.js" – Jakub Keller May 01 '22 at 19:22
  • You fixed my day, thanks! My problem was that I had before two folders, one for server and another one for the client app, containing each their own `package.json` with their own commands to start each application. After moving those to root folder of my project, swagger stopped working cause the path was not taking that change into account. Thanks! – WarioNeila86 Nov 05 '22 at 19:19
  • That was my issue as well and it works. Thanks. – Or Assayag Apr 26 '23 at 05:05
10

Try change apis path from apis: ['./routes/abc.js'] to apis: [`${__dirname}/routes/abc.js`] to make it the full path from the root folder. That works for me.

klee1611
  • 181
  • 2
  • 4
  • 1
    Pointing out this "apis" section sparked a fix for me. I recently changed over to TypeScript and needed to update the "apis" path to end with *.ts. – David Rachwalik Sep 20 '22 at 20:01
5

I was getting same issue for fastify. try to require() your routes after you register swagger. And magically, it worked for me. My case was:

When I registered routes before swagger, it was showing 'no operations defined in specs':

fastify.register(require("./routes/route")); //registered routes BEFORE swagger
fastify.register(require("fastify-swagger"), {

exposeRoute: true,

routePrefix: "/docs",

swagger: {

info: { title: "SWAGGER API" },

}

});
//gave that issue with no warnings / errors in terminal or browser console

This worked: registering routes after swagger

fastify.register(require("fastify-swagger"), {

exposeRoute: true,

routePrefix: "/docs",

swagger: {

info: { title: "SWAGGER API" },

}

});

fastify.register(require("./routes/route")); //registered routes after swagger
Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
Nishant Joshi
  • 61
  • 1
  • 6
  • No exposeRoute property anymore. Just remove exposeRoute and replace the swagger registration before the route registration line. – cacheoff Dec 06 '22 at 18:12
4

make apis full path like this apis: [__filename], it work for me

4

For me it worked when i added paths like below

 * @swagger
 * paths:
 *  /auth/login:
 *    post:
3bu1
  • 977
  • 12
  • 30
3

I solved this by changing URL from "../api/controllers/userController.js" to "./src/api/controllers/userController.js". So, you have to enter URL starting from root folder.

Jiyan
  • 31
  • 2
2

What helped me in .NET 6 was that I forgot to specify that I'm using controllers. This little piece of code fixed my issue in Program.cs:

builder.Services.AddControllers();
Syscall
  • 19,327
  • 10
  • 37
  • 52
Claudio Tejada
  • 239
  • 1
  • 4
  • 13
1

maybe if you use a similar configuration you need specify the root package of project "my.root.package"

@Bean
public Docket productApi(){
return new Docket(DocumentationType.SWAGGER_2).select()
           .apis(RequestHandlerSelectors.basePackage("my.root.package")).build();
        }
1

In .NET 6 don't forget to add

app.MapControllers();

along with

builder.Services.AddControllers();

(as mentioned by Syscall)

Enrico
  • 2,734
  • 1
  • 27
  • 40
1

Always start referring from the root of the application.

path

const path = require('path');

const options = {
    definition: {},
    apis: [path.join(process.cwd(), '/routes/*.routes.js')], 
};
0

I got this same error, I was able to solve it immediately I realise that I was referencing the wrong package.

@Bean
public Docket api() {
   return new Docket(DocumentationType.SWAGGER_2)
      .select()
      .paths(PathSelectors.any())
      .apis(RequestHandlerSelectors.basePackage("com.korede.liberations"))
      .build()
      .apiInfo(apiDetails());
}

Just in case anybody is having this same issue, check the package you're referencing in your

RequestHandlerSelectors.basePackage()

tgallei
  • 827
  • 3
  • 13
  • 22
Salami Korede
  • 339
  • 2
  • 9