[[:oktatas:web:back-end_framework:express:swagger|< Swagger]]
====== Express - Swagger automatikus generálása ======
* **Szerző:** Sallai András
* Copyright (c) 2023, Sallai András
* Szerkesztve: 2024
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]]
* Web: https://szit.hu
===== 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:
{
"scripts": {
"start":"nodemon app --watch app"
}
}
===== Szerver =====
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:
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 =====
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:
npm 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:
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:
"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:
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 ====
//...
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.
//...
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ó:
* https://swagger-autogen.github.io/docs/endpoints/manual-capture (2024)
==== Linkek ====
* https://swagger-autogen.github.io/docs/ (2024)