我们使用express用到最多的方案还是发布api接口,这里绕不开的就是swagger模块暴露api文档的便利性,那express【node】中如何引用相关的功能呢?
需要引入的包:
cnpm i swagger-jsdoc swagger-ui-express
这里以常用的文件上传接口为例
因为博主已使用了babel-node的方式,所以这里默认自带了
__dirname变量,同时导包方式也为import
【细节可以看本人node专栏下的express导包方案博文】
index.js 代码【服务入口文件】
import swaggerUi from 'swagger-ui-express';
import swaggerJsdoc from 'swagger-jsdoc';
let swaggerOptions = {
swaggerDefinition: {
openapi: '3.0.0',
info: {
description: 'Node Swagger API',
title: 'Swagger',
version: '1.0.0'
},
components: {
securitySchemes: {
Authorization: {
type: "http",
scheme: "bearer",
bearerFormat: "JWT",
value: "Bearer <JWT token here>"
}
}
},
servers: [{
url: '/'
}],
produces: ['application/json', 'application/xml'],
schemes: ['http', 'https'],
},
apis: [ path.join(__dirname, './controller/*.js')]
}
var swaggerSpec = swaggerJsdoc(swaggerOptions);
// 开放 swagger 接口
app.get('/swagger.json', function(req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(swaggerSpec);
});
// 使用 swaggerSpec 生成 swagger 文档页面,并开放在指定路由
app.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
fileController.js 代码
import express from 'express';
import fs from 'fs';
let apiRouter = express.Router();
import bodyParser from 'body-parser';
var jsonParser = bodyParser.json(); // 解析json解析器
var urlencodedParser = bodyParser.urlencoded({ extended: false });
// import jwtFunc from '../jwt.js'
// __dirname babel默认配置了相关的文件路径
var enableFileList = ["png","jpg","jpeg","bmp","gif","ico"];
/**
* @swagger
* /api/file/upload:
* post:
* tags:
* - File
* description: 上传文件
* produces: multipart/form-data
* requestBody:
* content:
* multipart/form-data:
* schema:
* type: object
* properties:
* file:
* type: string
* format: binary
* responses:
* 200:
* description: Successfully created
*/
apiRouter.post('/upload',async (req,res) => {
let fileObj = null;
let filePath = '';
if(!req.files || Object.keys(req.files).length === 0) {
// res.status(400).send({ code: 1, data: 'Bad Request.' })
res.send({ code: 500, data: '非法上传' })
return;
}
/* file 是上传时候body中的一个字段,有可以随意更改*/
fileObj = req.files.file;
if(!fileObj) {
res.send({ code: 500, data: '非法上传' })
}
let splitArr = fileObj.name.split('.');
let ext = splitArr[splitArr.length-1].toLowerCase();
if( enableFileList.indexOf(ext) == -1) { // 文件不在允许文件范围内
return res.send({ code: 500, msg: '非法的文件类型' })
}
// 检查是否存在文件存储相关文件夹
let exist = fs.existsSync(__dirname+'/../../webFile/');
if(!exist) {
fs.mkdirSync(__dirname+'/../../webFile/');
console.log('初次部署,已创建用于文件存储的文件夹,地址为 ../webFile');
}
filePath = __dirname+'/../../webFile/';
if(req.body.fCode) {
let exist = fs.existsSync(__dirname+'/../../webFile/'+req.body.fCode);
if(!exist) {
fs.mkdirSync(__dirname+'/../../webFile/'+req.body.fCode);
}
filePath = filePath + req.body.fCode + '/';
}
filePath = filePath + fileObj.md5;
fileObj.mv(filePath, (err) => {
if(err) {
return res.send({ code: 500, msg: '上传失败' })
}
res.send({ code: 200, data: '上传成功', md5: fileObj.md5 });
})
})
/**
* @swagger
* /api/file/download:
* get:
* tags:
* - File
* description: 获取文件
* produces: application/json
* parameters:
* - name: fname
* in: query
* schema:
* type: string
* responses:
* 200:
* description: Successfully created
*/
apiRouter.get('/download',urlencodedParser,async (req,res) => {
let filePath = __dirname+'/../../webFile/' + req.query.fname;
let exist = fs.existsSync(filePath);
if(exist) {
res.download(filePath);
} else {
res.send({ code: 500, msg: '文件不存在' });
}
});
export default apiRouter
经过@swagger注解会自动生成相应的json内容,并暴露在/swagger路径,方便接口对接
如下图:
接口对接可以直接在swagger页面测试,具体的swagger食用方案请参考其他更专业的博文