express-api的注解规范-swagger

我们使用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食用方案请参考其他更专业的博文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值