Tartalomjegyzék

< Swagger

Express - Swagger automatikus generálása

Projekt

mkdri app01
cd app01
npm init -y

Függőségek:

pnpm install --save express nodemon morgan
pnpm install --save-dev swagger-jsdoc swagger-ui-express

Script:

package.json
{
  "scripts": {
    "start":"nodemon app --watch app"
  }
}

Szerver

app/index.js
const express = require('express')
const app = new express()
const morgan = require('morgan')
const router = require('./routes/api')
 
const PORT = process.env.PORT || 8000;
 
app.use(express.json())
app.use(morgan('tiny'))
app.use(router)
 
app.listen(PORT, () => {
    console.log('Server is running on port: ', PORT)
})

A Swagger beépítése

Az index.js fájlban:

//...
const swaggerUi = require('swagger-ui-express')
const swaggerDocument = require('../swagger-output.json')
 
app.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerDocument))
//...

Az utolsó sor szétbontható két részre. A teljes fájlban így fog szerepelni.

A teljes fájl:

index.js
const express = require('express')
const app = new express()
const morgan = require('morgan')
const router = require('./routes/api')
 
const swaggerUi = require('swagger-ui-express')
const swaggerDocument = require('../swagger-output.json')
 
const PORT = process.env.PORT || 8000;
 
app.use('/swagger', swaggerUi.serve)
app.get('/swagger', swaggerUi.setup(swaggerDocument))
 
app.use(express.json())
app.use(morgan('tiny'))
 
app.use('/api', router)
 
app.listen(PORT, () => {
    console.log('Server is running on port: ', PORT)
})

A Swagger most egy JSON fájlból dolgozik aminek a neve most: swagger-output.json. A fájl viszont most automatikusan generálódik.

Routing

routes/api.js
const router = require('express').Router();
 
const EmployeeController = require('../controllers/employeecontroller');
 
router.get('/employees', EmployeeController.index)
router.post('/employees', EmployeeController.store)
 
module.exports = router

Automatikus Swagger generálás

Szükségünk van egy újabb csomagra:

pnpm install --save-dev swagger-autogen

Készítsünk a projekt gyökérkönyvtárában egy swagger.js fájlt, a következő tartalommal:

swagger.js
const swaggerAutogen = require('swagger-autogen')({openapi: '3.0.0'});
 
const doc = {
  info: {
    title: 'Dolgozók REST API',
    description: 'Teszt'
  },
  servers: [
    {
        url: 'http://localhost:8000/api',
        description: ''
    }
  ]
};
 
const outputFile = './swagger-output.json';
const routes = ['./app/routes/api.js'];
 
swaggerAutogen(outputFile, routes, doc);

Írjunk egy scriptet a package.json fájlban:

package.json
  "scripts": {
    "start": "node app",
    "dev": "nodemon app --watch app",
    "doc": "node ./swagger.js"
  },

A futtatás:

npm run doc

A kontrollerben szerepelnie kell önmagában vagy szelekcióban a kötelező mezőknek.

        req.body.name
        req.body.city
        req.body.salary
        req.body.positionId

Teljes kód:

app/controllers/employeecontroller.js
    async store(req, res) {
 
        req.body.name
        req.body.city
        req.body.salary
        req.body.positionId
 
        try {
            await EmployeeController.tryStore(req, res)
        } catch (error) {
            if (error instanceof Sequelize.ValidationError) {
                res.status(400)
            }else {
                res.status(500)
            }
            const errorMessage = error.errors[0].message
            res.json({
                success: true,
                message: 'Error! The update is failed!',
                error: errorMessage
            })
        }        
    },
    async tryStore(req, res) {
        const emp = await Employee.create(req.body)
        res.status(201)
        res.json({
            success: true,
            data: emp
        })
    },

A store függvényben ellenőrzéssel

app/controllers/employeecontroller.js
//...
    async store(req, res) {
        if(!req.body.name ||
            !req.body.city ||
            !req.body.salary ||
            !req.body.positionId) {
            res.status(400)
            res.json({
                success: false,
                message: 'Hiba! A bejövő adatok hibásak!'
            })
        }
 
        try {
            await EmployeeController.tryStore(req, res)
        } catch (error) {
            if (error instanceof Sequelize.ValidationError) {
                res.status(400)
            }else {
                res.status(500)
            }
            const errorMessage = error.errors[0].message
            res.json({
                success: true,
                message: 'Error! The update is failed!',
                error: errorMessage
            })
        }        
    },
    async tryStore(req, res) {
        const emp = await Employee.create(req.body)
        res.status(201)
        res.json({
            success: true,
            data: emp
        })
    },
//...

Body paraméterek haladó módon

Swagger annotációt fogunk használni a body paraméterek értelmezésére.

app/controllers/employeecontroller.js
//...
 
    async store(req, res) {
    /*
        #swagger.parameters['body'] = {
            in: 'body',
            description: 'Dolgozó adatai',
            required: true,
            schema: {
                name: "Valaki",
                city: "Valahol",
                salary: 300.0,
                positionId: 1
            }
        }
    */
 
        try {
            const emp = await Employee.create(req.body)
            res.status(201)
            res.json({
                success: true,
                data: emp
            })
        } catch (error) {
            res.status(500)
            res.send('Hiba')
        }
    },
 
//...

Közvetlen dokumentáció:

Linkek