45

前端对API接口的封装和管理

 5 years ago
source link: https://www.tuicool.com/articles/QbUJbi2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作为一名前端同学,主要工作就是数据的展示和处理用户的可视化交互。

其中一定少不了要和后端打交道,而API接口就是前端和后端之间的桥梁,后端同学按照约定好的接口格式返回前端所需要的数据,前端同学通过HTTP请求获取数据并呈现在用户面前。所以今天我们来谈谈前端对API接口的封装以及管理

业务层的封装

有了适配层的封装,我们可以更专注于业务上的逻辑处理,为了提高代码的复用性,我们可以根据业务需求,在适配层的基础上再加一层业务层。

业务层可以做的东西很多,主要根据不同项目的需求进行定制,以下是一些我曾使用过或者比较常见的一些操作

  • 添加鉴权操作
  • 错误/警告弹窗提示以及重定向
  • 监控日志埋点

接口数据规范化

接口同步

实现思路:解析接口文档,获取相应的数据结构,进行数据的筛选,解析成我们需要的数据,同时配合模板自动生成我们所需要的文件,具体看一下实现方案,以swagger为例: uUfQRbY.jpg!web 首先解析swagger语法获取相应的数据并筛选出需要的数据

import Swagger from 'swagger-client'

Swagger({ url: "http://petstore.swagger.io/v2/swagger.json" }).then((client) => {  
    client
      .apis
      .pet // tag name == `pet`
      .addPet({ // operationId == `addPet`
        id: 1,
        body: {
          name: "bobby",
          status: "available"
        }
      })
      .then(...)
})

支持接口模块化

配置接口模块化配置文件,可以减少不必要的文件搜索,提升检测效率

module.exports = {  
    template: '', // 可为空使用默认接口生成模板
    generateType: '', // 默认不要写
    safe: true, // 是否生成保护数据
    output: "src/api", // 输出到api目录
    projectDir: "src", // 代码存放目录(可不配置默认为src路径)
    suffix: [".js",".vue"], // 指定查询的文件(可不配置,默认.js,.vue文件)
    projects: [{
        token: '值', // swagger令牌
        modelName: "demo1", // 模块化名称
        docUrl: ['api-docs', 'api-docs', 'api-docs', 'api-docs']  // swagger base-url
    }, {
        token: '值', // swagger令牌
        modelName: 'demo2',
        docUrl: ['api-docs'] // 多个
    }] // 项目配置
};

baiMZjU.png!web

接口检测,对丢失的接口进行提示,并清楚冗余的接口

通过对项目中所有的接口进行匹配来校验出接口当前是否被使用,同时可以对未被检测到的接口进行删除,这样一来,可以大大减少接口文件内容。

function __handleAPIFile(project, projectPath, config) {  
    var filePath = projectPath + '/' + config.output + '/' + project + '/index.js';
    let file = fs.readFileSync(filePath, 'utf8');
    let lines = file.split("\n");
    let i = 0;
    let step = 10;
    let newLineArr = [];
    let matchArr = [];

    var get_line = (begin, end) => {
        var arr = [];
        var flag = false;

        for (let j = begin; j < end; j++) {
            if (i === lines.length - 1) {
                return ;
            } else {
                arr.push(lines[j]);

                cache[project].forEach(item => {
                    if (new RegExp("function " + item, "g").test(lines[j])) {
                        matchArr.push(item);
                        flag = true;
                    }
                });

                if (lines[j] === '') {
                    i = j + 1;
                    break;
                }
            }
            i = j + 1;
        }

        if (flag || begin === 0) {
            newLineArr = newLineArr.concat(arr);
        }

        get_line(i, i + step);
    };

    get_line(i, i + step);

     matchArr = _.uniq(matchArr)

    __checkAPI(matchArr, project, config);

    __write(newLineArr, matchArr, filePath, project);

    // 清空缓存
    lines = null;
    newLineArr = null;
}

function __checkAPI(arr, project, config) {  
    if (arr.length !== cache[project].length) {
        var longArr = arr.length < cache[project].length ? cache[project] : arr;
        var shortArr = arr.length < cache[project].length ? arr : cache[project];
        var lose = [];

        longArr.forEach(item => {
            if (shortArr.indexOf(item) === -1) {
                lose.push(item);
            }
        });

        if (lose.length !== 0) {
            logger.log(chalk.yellow(config.output + '/' + project + '/index.js 文件里, 没有找到以下方法:'));
            lose.forEach(item => {
                logger.log(item);
            });
        }
    }
}

YRbuQz2.png!web 这样以来我们就可以统一对接口进行管理,无论是更新还是清除冗余,都可独立的处理

最后

最后附上这个工具地址,及使用方法,欢迎各位大佬指导 接口管理工具


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK