Forum Discussion

djGaston's avatar
djGaston
New Contributor
5 years ago

Error: "No operations defined in spec!" - using ES6 Node Express with Consign & Swagger

Hi guys,

I've worked with API before, but I've always wanted to work with a well documented API.

My problem is that I've started a React Native project that needs to consume my own API, but we're using ES6 javascripts with this stack: MERN (MySQL, Express, React, Nodejs). Over that, we use Consign to handle the starting of the server.

My implementation of Swagger is giving me "No operations defined in spec!".
I've created a Stackoverflow post, but I'm also copying the issue here, too. 

https://stackoverflow.com/questions/62323480/no-operations-defined-in-spec-es6-node-express-swagger

 

I'm failing to make Swagger pick up all the routes defined in the property "apis: ['./routes/*.js']".

 

{
"info": {
"title": "my",
"description": "my API",
"contact": {
"name": "me"
},
"servers": [
"http://localhost:3000"
]
},
"swagger": "2.0",
"paths": {},
"definitions": {},
"responses": {},
"parameters": {},
"securityDefinitions": {},
"tags": []
}

This is my modified code: index.js

const express = require('express');
const app = express();
const consign = require('consign');

const swaggerJsDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
const bodyParser = require('body-parser');

const port = process.env.PORT || 3000;

const swaggerOptions = {    swaggerDefinition: {        info: {            title: 'my',            description: 'my API',            contact: {                name: 'me'
            },            servers: ['http://localhost:' + port]
        }
    },    swagger: '2.0',    basePath: '/v1',    schemes: [
        'http',
        'https'
    ],    consumes: [
        'application/json'
    ],    produces: [
        'application/json'
    ],    apis: ['./routes/*.js']
}

// Routesconsign({cwd: __dirname})
  .include('libs/config.js')
  .then('db.js')
  .then('libs/middlewares.js')
  .then('routes')
  .then('libs/boot.js')
  .into(app);

const swaggerDocs = swaggerJsDoc(swaggerOptions);app.use(bodyParser.json());app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs))

// serve swagger (http://localhost:3000/swagger.json)app.get('/swagger.json', function(req, res) {    res.setHeader('Content-Type', 'application/json');    res.send(swaggerDocs);
});

tasks.js

module.exports = app => {

  const Task = app.db.models.Task;

    /**
    * @swagger
    * /tasks:
    *  get:
    *    description: Use to request all customers
    *    responses:
    *      '200':
    *        description: A successful response
    */    app.route('/v1/tasks').get((req, res) => {
      Task.findAll({})
        .then(result => res.json(result))
        .catch(error => {          res.status(412).json({msg: error.message});
        });
    });

    /**
    * @swagger
    * /tasks:
    *  post:
    *    description: Use to insert the json content
    *    responses:
    *      '200':
    *        description: A successful response
    */    app.route('/v1/tasks').post((req, res) => {
      Task.create(req.body)
        .then(result => res.json(result))
        .catch(error => {          res.status(412).json({msg: error.message});
        });
    });

    /**
    * @swagger
    * /tasks/{id}:
    *  get:
    *    description: Use to request one customer
    *    responses:
    *      '200':
    *        description: A successful response
    */    app.route('/v1/tasks/:id').get((req, res) => {
      Task.findOne({where: req.params})
        .then(result => {
          if (result) {            res.json(result);
          } else {            res.sendStatus(404);
          }
        })
        .catch(error => {          res.status(412).json({msg: error.message});
        });
    });

    /**
    * @swagger
    * /tasks/{id}:
    *  put:
    *    description: Use to update a record with the json content
    *    responses:
    *      '200':
    *        description: A successful response
    */    app.route('/v1/tasks/:id').put((req, res) => {
      Task.update(req.body, {where: req.params})
        .then(result => res.sendStatus(204))
        .catch(error => {          res.status(412).json({msg: error.message});
        });
    });

    /**
    * @swagger
    * /tasks/{id}:
    *  delete:
    *    description: Use to delete a record
    *    responses:
    *      '200':
    *        description: A successful response
    */    app.route('/v1/tasks/:id').delete((req, res) => {
      Task.destroy({where: req.params})
        .then(result => res.sendStatus(204))
        .catch(error => {          res.status(204).json({msg: error.message});
        });
    });

};

 

  • HKosova's avatar
    HKosova
    5 years ago

    There's some confusion about what "Swagger" means. "Swagger" refers to a family of tools developed by SmartBear. Our Swagger tools are listed on the https://swagger.io website and published on GitHub in the "Swagger" organization: https://github.com/swagger-api.

     

    Some third-party community projects also use "Swagger" in their names - even though they are not related to SmartBear Swagger tools.

     

    swagger-jsdoc and swagger-ui-express are examples of such third-party community projects. (swagger-ui-express is not the same as our Swagger UI, but uses it internally.) The best way to get support with these projects would be to open an issue in their respective repositories:
    https://github.com/scottie1984/swagger-ui-express

    https://github.com/Surnet/swagger-jsdoc