美文网首页
express集成swagger

express集成swagger

作者: HoPGoldy | 来源:发表于2019-05-14 15:34 被阅读0次

    在使用的过程中我又发现了另一个更加好用的轮子 express-swagger-generator,这个轮子的配置更简单,使用也更加的方便,接下来就简单的介绍一下,之前的配置方式在下面:

    引入 express-swagger-generator

    安装

    yarn add express-swagger-generator
    

    app.js 中引用

    const express = require('express');
    const app = express();
    const expressSwagger = require('express-swagger-generator')(app);
    
    let options = {
        swaggerDefinition: {
            info: {
                description: 'This is a sample server',
                title: 'Swagger',
                version: '1.0.0',
            },
            host: 'localhost:3000',
            basePath: '/v1',
            produces: [
                "application/json",
                "application/xml"
            ],
            schemes: ['http', 'https'],
            securityDefinitions: {
                JWT: {
                    type: 'apiKey',
                    in: 'header',
                    name: 'Authorization',
                    description: "",
                }
            }
        },
        basedir: __dirname, //app absolute path
        files: ['./routes/**/*.js'] //Path to the API handle folder
    };
    expressSwagger(options)
    app.listen(3000);
    

    观察可以发现这个包的配置文件和swagger-ui的是很像的,所以可以很轻松的进行迁移,并且集成完成后就可以用更简单的jsdoc来描述接口了,这可比写yaml格式的注释不知道高到哪里去了:

    /**
     * This function comment is parsed by doctrine
     * @route GET /api
     * @group foo - Operations about user
     * @param {string} email.query.required - username or email - eg: user@domain
     * @param {string} password.query.required - user's password.
     * @returns {object} 200 - An array of user info
     * @returns {Error}  default - Unexpected error
     */
    exports.foo = function() {}
    

    以下为原文:


    express 作为一个 node 服务端框架,当然少不了各种的接口,我之前的项目都是通过 jdoc 样式来说明接口,但是这样的表达能力依旧略显单薄,所以这里就记录下如何在 express 框架里集成大名鼎鼎的 swagger 来规范化后端接口:

    使用 jdoc 说明接口

    /**
     * 设置活动状态
     * 
     * @param {String} activityId 活动ID
     * 
     * @memberof activity
     */
    router.post('/setActivityNextState', (req, res) => {
        ...
    })
    

    使用 swagger 说明接口

    swagger访问页面

    接入过程

    想在 express 里接入 swagger 需要两个包swagger-jsdocswagger-ui-express,前者将 jsdoc 格式的注释转化为 swagger 类型的 json,后者使用这个 json 生产对应的 swagger 页面,所以说,接入成功之后我们给接口写的 jsdoc 注释就会自动生成为 swagger 文档页面。

    安装

    yarn

    yarn add swagger-jsdoc swagger-ui-express
    

    npm

    npm install swagger-jsdoc swagger-ui-express --save
    

    引入

    首先打开app.js,在let app = express()下面加上这一段代码

    import swaggerUi from 'swagger-ui-express'
    import swaggerJSDoc from 'swagger-jsdoc'
    import path from 'path'
    
    // 配置 swagger-jsdoc
    const options = {
        definition: {
            // swagger 采用的 openapi 版本 不用改
            openapi: '3.0.0',
            // swagger 页面基本信息 自由发挥
            info: {
                title: 'Express Template',
                version: '1.0.0',
            }
        },
        // 重点,指定 swagger-jsdoc 去哪个路由下收集 swagger 注释
        apis: [ path.join(__dirname, '/router/*.js') ]
    }
    
    const swaggerSpec = swaggerJSDoc(options)
    
    // 开放 swagger 相关接口,
    app.get('/swagger.json', function(req, res) {
      res.setHeader('Content-Type', 'application/json');
      res.send(swaggerSpec);
    });
    
    // 使用 swaggerSpec 生成 swagger 文档页面,并开放在指定路由
    app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
    

    注意,这段代码里使用了import / from,请确保你的项目引入了babel等语法编译器。其中最后一行代码,那里指定了你 swagger 文档页面的路由,这时候启动项目然后访问 localhost:3000/api-docs/ 就可以看到 swagger 页面了。

    一个什么接口都没有的swagger文档

    给接口写文档

    如果上一步你已经完成的话就说明已经集成成功了,接下来就是给每个接口写对应的 swagger 文档,格式如下:

    /**
     * @swagger
     * /hello:
     *   get:
     *     tags:
     *       - 测试
     *     summary: GET 测试
     *     description: 用于测试基础 GET 请求的接口
     *     responses:
     *       200:
     *         description: 【成功】 返回 world
     */
    router.get('/hello', (req, res) => {
        res.send('world')
    })
    

    找到你的接口,在它上面 @swagger 之后,这一块的注释就会被swagger-jsdoc找到并解析成对应的 yaml 文档,标准的 swagger 文档使用 yaml 格式书写。这里推荐一个 在线 swagger 编辑器

    在你完成了上面的工作之后重启 express 服务就可以在 localhost:3000/api-docs/ 路由下看到你刚才写的接口了。等一下,你说你的 swagger 里还是啥都没有?看下一节。

    找不到接口文档

    如果你可以打开 swagger 页面,但是在接口上面无论怎么写它都不会同步到 swagger 页面里,那么就有可能是刚才app.jsoptions.apis这个属性的配置出现了问题,swagger-jsdoc服务就是根据这个属性来寻找你的接口所在文件的,这里最好使用path.join()来明确路由,js 里直接写的相对路由很坑的,只要这里生成的绝对路径可以正确指向你的路由接口所在文件,那么这个问题就自然的解决了。

    封装

    如果你觉得把所有的代码都写到app.js里很丑陋的话,那么恭喜你,这一小节就是为你准备的,如果你喜欢到处封装的话,那你肯定有一个config.js文件,在加上我们要封装出的swagger文件和app.js,这三个的目录关系如下:

    app.js ------------ 项目入口
    config.js --------- 静态配置文件
    /swagger
    ├── index.js ------ swagger封装文件
    

    为啥要给swagger多建一层目录,我也不知道,担心以后会有 swagger 相关的文件出现,到时候就可以直接放在这个目录下。下面是具体的代码和说明:

    swagger/index.js
    这里引入了两个需要的包,并从config.js中获取配置,这一块的主要内容就是文章开头的代码修改了其中的静态配置项,并封装为一个用于设置 swagger 的方法

    import swaggerUi from 'swagger-ui-express'
    import swaggerJSDoc from 'swagger-jsdoc'
    import { swaggerConfig } from '../config'
    
    export default function setSwagger(app) {
        const options = {
            definition: {
                openapi: swaggerConfig.openapi,
                info: {
                    title: swaggerConfig.title,
                    version: swaggerConfig.version
                }
            },
            apis: swaggerConfig.apis
        }
    
        const swaggerSpec = swaggerJSDoc(options)
    
        app.get('/api-docs.json', (req, res) => {
            res.setHeader('Content-Type', 'application/json')
            res.send(swaggerSpec)
        })
    
        app.use(swaggerConfig.routerPath, swaggerUi.serve, swaggerUi.setup(swaggerSpec))
    }
    

    config.js
    这里引入了path模块,注意其中的apis属性可能会因为你项目里app.jsconfig.js的路径不同而发生变化

    import path from 'path'
    
    // swagger配置信息
    export const swaggerConfig = {
        openapi: '3.0.0',
        title: 'Express Template',
        version: '1.0.0',
        apis: [
            path.join(__dirname, '/router/*.js')
        ],
        routerPath: '/api-docs'
    }
    

    app.js
    封装好后直接引入对应方法,并把app当做参数传过去即可

    // 引入swagger
    import setSwagger from './swagger'
    setSwagger(app)
    

    参考

    相关文章

      网友评论

          本文标题:express集成swagger

          本文链接:https://www.haomeiwen.com/subject/lousaqtx.html