简体   繁体   中英

No operations defined in spec! - ES6 Node Express Swagger

I've cloned a working API from a repository and tried to configure Swagger (openAPI).

1) original without Swagger ( npm run dev ): https://github.com/FaztWeb/nodejs-sequelize-rest-api.git

2) my clone with Swagger ( npm run dev ): https://github.com/djgaston/node-express-swagger.git

The stack includes Node.js + Express + SQLite3 , but uses javascript ES6 , complicating the router method. Also, it uses Consign ( https://www.npmjs.com/package/consign ) and Sequelize ( https://www.npmjs.com/package/sequelize ).

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

When I run the project, the swagger documentation include a message saying "No operations defined in spec!" and the swagger.json files confirms it not found the files.

{
"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']
}

// Routes
consign({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});
        });
    });

};

I have the same problem, I tried with apis: ['.routes/*.js'], and apis: ['./routes/*.js'], but doesn't works.

app.js

const express = require('express');
const cors = require('cors');
const imageRouter = require('./routes/imageRouter');
const swaggerUI = require('swagger-ui-express');
const swaggerJsDoc = require('swagger-jsdoc');

const options = {
    definition: {
        openapi: "3.0.0",
        info: {
            title: "My App API",
            version: "1.0.0",
            description: "My API",
        },
        servers: [
            {
                url: "http://localhost:4000"
            },
        ],
    },
    apis: ['./routes/*.js'], // and ['.routes/*.js'],
}

const specs = swaggerJsDoc(options);

const app = express();

app.use(cors())
app.use(express.json())

require('./config/dbseed')

app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(specs))

app.use('/api/v1/', imageRouter)

module.exports = app;`

./routes/imageRouter.js

const router = require('express').Router();
const imageController = require('../controllers/imageController');
const validateBody = require('../middlewares/validateBody');
const upload = require('../aws/S3')

/**
 * @swagger
 * components:
 *   schemas:
 *     Image:
 *       type: object
 *       required:
 *         - url
 *         - name
 *         - email
 *         - phone
 *       properties:
 *         id:
 *           type: string
 *           description: The auto-generated id of the Image
 *         url:
 *           type: string
 *           description: The Image location
 *         name:
 *           type: string
 *           description: The Image name description
 *         email:
 *           type: string
 *           description: The Image email associated
 *         phone:
 *           type: string
 *           description: The Image phone associated
 *       example:
 *         id: 7
 *         name: Vancouver 
 *         email: vancouver@gmail.com
 *         phone: 17788196354
 */

/**
 * @swagger
 * /image:
 *   post: 
 *     description:
 *     responses: 
 *       '200':
 *         description: Image uploaded successfully
 */

router.post('/image', upload.single('image'), validateBody, imageController.upload);
router.get('/images', imageController.gallery);

module.exports = router;`

What am I doing wrong?

No operations defined in spec!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM