从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API

摘要:
该公司在以前的项目中使用swagger来配置python模型的API,这感觉非常容易使用。Swagger可以提供请求、响应甚至错误认证机制,这非常方便。我们需要使用的库主要是swagger-ui-express,它将提供与swagger相关的功能和一个易于查看和调试的ui。我们添加一个swagger文件夹并添加配置文件swagger。由于我们的swagger文件是yaml文件,所以我们需要yamljs库来读取它。

之前公司做项目是用过swagger来配置python模型的API,感觉非常好用。swagger可以提供request, response甚至error的验证机制,十分便利。node当然也可以用啦。

我们需要使用的库主要是swagger-ui-express,它将提供swagger的相关功能以及一个UI,方便查看和调试。

1、初始设定

老规矩,我们还是通过express work_with_swagger来新建一个叫work_with_swagger的项目。然后依旧是删除bin文件夹,改改app.js以及将package.json中的start改为node app.js(当然,用nodemon会更好,可以安装npm install nodemon,然后将start改为nodemon app.js)。

var express = require('express');

var app = express();

app.use(express.urlencoded({extended: true}));  //解析json用
app.use(express.json()); //解析json用

app.listen(5000, function() {
    console.log('App listening on port 5000...')
});

然后我们来做些设置:

我们会有一个Controller来负责request -> response的逻辑。

我们将原来的routes删掉,增加自己的路由Routes,对接到对应的controller。

我们添加一个swagger文件夹,并在其中加入我们的配置文件swagger.yml。

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第1张

2、添加swagger-ui-express

现在,我们需要改动一下app.js来把swagger配置文件包含进去。由于我们的swagger文件是yaml文件,所以我们需要yamljs库来读取它(默认只能读取json格式的swagger文件,直接抄https://www.npmjs.com/package/swagger-ui-express提供的方法)。

此外,我们把路由文件也加入进去。

var express = require('express');
var swaggerUi = require('swagger-ui-express');
var YAML = require('yamljs');

const swaggerDocument = YAML.load('./swagger/swagger.yml');
const RandomRouter = require('./Routes/RandomRouter');

var app = express();

app.use(express.urlencoded({extended: true}));  //解析json用
app.use(express.json()); //解析json用
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
app.use('/', RandomRouter)

app.listen(5000, function() {
    console.log('App listening on port 5000...')
});

我们现在可以象征性地写几个controllers并把他们加入路由文件中,2个get,1个post:

var express = require('express');
var YAML = require('yamljs');

exports.healthCheck = (req, res) => {
    const swaggerDocument = YAML.load('./swagger/swagger.yml');
    res.status(200).send(
        {
            message:'耗子尾汁',
            version:swaggerDocument['info']['version']
        }
    )
};

exports.setAge = (req, res) => {
    console.log(req)
    var age = req.query.number
    res.status(200).send(`来骗,来偷袭,我${age}岁的老同志`)
};

exports.tricks = (req, res) => {
    var tricks = req.body.tricks
    var comment = req.body.comment

    var line = tricks.join(', ') + ', ' + comment
    res.status(200).send(line)
};
var express = require('express');
const RandomController = require('../Controllers/RandomController');

var router = express.Router();

router.get('/age', RandomController.setAge);
router.post('/tricks', RandomController.tricks);
router.get('/', RandomController.healthCheck);

module.exports = router;

接下来,我们来配置一下swagger.yml(yaml文件写长了真是需要游标卡尺……):

openapi: 3.0.0
info:
  title: Work with Swagger
  description: This is just an experiment
  version: v1.0

servers:
- url: http://localhost:5000

paths:
  /:
    get:
      summary: Health check endpoint
      operationId: healthCheck
      responses:
        200:
          description: Successful operation
        400:
          description: Bad request
        404:
          description: Not found

  /age:
    get:
      summary: Set the age of the user
      parameters:
      - name: number
        in: query
        description: The age of the user
        required: true
        schema:
          type: integer
          format: int64
      responses:
        200:
          description: Successful operation
        400:
          description: Bad request
        404:
          description: Not found

  /tricks:
    post:
      summary: Hit by some tricks
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tricks'
      responses:
        200:
          description: Successful operation
        400:
          description: Bad request
        404:
          description: Not found

components:
  schemas:
    tricks:
      type: object
      required:
      - tricks
      - comment
      properties:
        tricks:
          type: array
        comment:
          type: string

这里我们对每个路由节点做出了一些规定,比如对于/age,我们规定query中传入的参数number只能是整数;比如对于/tricks,传入的json一定要包含tricks和comment等等(也就是规定了schema)。

这里我们可以用2种不同的方式来规定schema:一种是直接在节点部分的schema下继续下写去(例如/age节点那样);另一种是单独写在components的schemas下面,而在节点的schema处用$ref来指定引用(例如/tricks节点那样)。

OK,差不多完工了,现在我们进入UI界面看一看效果,输入http://localhost:5000/api-docs/,会出现这样一个界面:

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第2张

点开某个节点(此处为/age/{number}),就能看到我们对该节点的一些设置:

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第3张

点击Try it out之后就可以输入query,我们输入一个整数试试,点击Execute:

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第4张

如果我们试图输入string,会发现无法Execute:

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第5张

看来效果不错。但swagger-ui-express毕竟只是类似于一个文档工具,点到为止。我们在Postman中试试,会发现其实根本没有验证机制的存在……

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第6张

3、补上验证机制

虽然验证要以和为贵,但不能光点到为止啊,看来我们还需要另一个验证工具,那就是openapi-express-validator。

我们用npm install openapi-express-validator来完成安装,然后再在app.js中加入一些内容:

var express = require('express');
var swaggerUi = require('swagger-ui-express');
var YAML = require('yamljs');
var OpenApiValidator = require('express-openapi-validator');

const swaggerDocument = YAML.load('./swagger/swagger.yml');
const RandomRouter = require('./Routes/RandomRouter');

var app = express();

app.use(express.urlencoded({extended: true}));  //解析json用
app.use(express.json()); //解析json用
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

// 新增,指定一下swagger文件
const spec = './swagger/swagger.yml';
app.use('/spec', express.static(spec));

// 将OpenApiValidator加入中间件
app.use(
  OpenApiValidator.middleware({
    apiSpec: './swagger/swagger.yml',
    validateRequests: true,
    //validateResponses: true, // 如果需要验证response,则设为true
  }),
);

app.use('/', RandomRouter)

app.use((err, req, res, next) => {
  // 配置错误信息
  res.status(err.status || 500).json({
    message: err.message,
    errors: err.errors,
  });
});

app.listen(5000, function() {
  console.log('App listening on port 5000...')
});

现在我们再来试试:

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第7张

这次没问题了,我们得到了一个错误信息,提示我们params中的number应该是整数。

从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API第8张

输入整数则没有问题,验证功能完成了。

代码见:

https://github.com/SilenceGTX/work_with_swagger

免责声明:文章转载自《从零开始的野路子React/Node(7)将Swagger(OpenAPI)运用于后端API》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Lua和C的语法差别使用批处理创建永久生效的环境变量下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

node爬虫爬取中文时乱码问题 | nodejs gb2312、GBK中文乱码解决方法

iconv需要依赖native库,这样一来,在一些不支持native模块安装的虚拟主机和windows平台上,我们还是无法安心处理GBK编码。 老外写了一个通过纯Javascript转换编码的模块 iconv-lite 可以实现window下的转换 ,通过npm可以安装此模块,bufferhelper是一个操作buffer的加强类 首先安装 npm ins...

xpath 函数大全

在本文的第一部分中,我们介绍了XPath并讨论了各种各样的从简单到复杂的XPath查询。 通过把XPath查询应用到XML示例文件,我们详细说明了各种重要的XPath定义比如location step、context node、location path、axes和node - test。 我们然后讨论了多个简单查询组合成的复杂的XPath查询。 我们还讨...

2-k8s笔记-Kubernetes安装配置指南

第2章 Kubernetes安装配置指南2.1 系统要求2.2 使用kubeadm工具快速安装Kubernetes集群2.2.1 安装kubeadm和相关工具2.2.2 kubeadm config2.2.3 下载Kubernetes的相关镜像2.2.4 运行kubeadm init命令安装Master2.2.5 安装Node,加入集群2.2.6 安装网络...

ES数据库安装6.6

ES数据库安装 elastica searchelasticsearch的概念:是一个实时的分布式搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析。它是一个建立在全文搜索引擎 Apache Lucene 基础上的搜索引擎,使用 Java 语言编写。 1、elasticsearch和MongoDB/redis/memcache一样,是非关系性数据库是一...

单项目实现vendor分离编译,增加编译效率(vue-cli)

1、在build文件夹下添加文件:webpack.dll.config.js const path = require('path') const webpack = require('webpack') const package = require('../package.json') const AssetsPlugin = require('ass...

部署CentOS,集成Mysql、Nodejs、Nginx

1. Mysql安装 Step 1 安装源 https://dev.mysql.com/downloads/repo/yum/ 选择:Red Hat Enterprise Linux 8 / Oracle Linux 8 (Architecture Independent), RPM Package 这个download 跳转的页面对着No thanks,...