「Yapi 改造计划二」接口模板预检

667 阅读2分钟

Mock 之前先对接口模板的复杂度进行检测,复杂度过高时放弃 mock,以防主站服务被拖挂。

改造原因

先介绍下 Yapi 基础的 mock 逻辑,首先需要用户定义 API 的基础信息,请求、返回等信息,返回数据将被存储为描述 response 的抽象对象模板,mock 服务根据这份模板,生成一份具体的 mock 数据,生成是由 json-schema-faker 这个库完成,下文中我们将简称为 jsf,mock 服务将生成的 mock 数据返回,就完成了一次最基础的 mock。

问题

这部分的逻辑没问题,但随时可能造成整个 Yapi 服务挂掉,这里没有危言耸听,交由 jsf 处理的模板如果嵌套层级过多,处理复杂度陡省,耗费时间和资源增加,直到触发系统 GC(内存回收),服务崩溃。

方案

我们的解决方案是在模板数据交由 jsf 处理前,先进行嵌套深度检测,如果嵌套层级过多,直接跳过 mock,避免拖垮整站服务,检测代码如下:

const depthDetect = (objectData, depth = 0) => {
  let newDepth = depth
  if (objectData instanceof Array) {
    for (let index of objectData) {
      let resDepth = depthDetect(objectData[index], depth + 1)
      newDepth = Math.max(newDepth, resDepth)
    }
  } else if (objectData instanceof Object) {
    let keys = Object.keys(objectData)
    for (let index of keys) {
      let resDepth = depthDetect(objectData[index], depth + 1)
      newDepth = Math.max(newDepth, resDepth)
    }
  }
  return newDepth
}
}

经过多次测试,将嵌套深度限制在 30 层内,可以保证稳定的服务运行。

优化方向

无法预测研发人员定义的接口复杂度,不能在用户端限制用户编辑的接口嵌套深度,因此选择在 mock 前进行检测,这一步流程可以优化至接口模板保存时,保存时校验接口嵌套深度,并进行标记。

Yapi 是很优秀的一款 API 管理及 Mock 工具,日常开发过程中,可以用于接口管理规范化同时提升团队间的沟通协作体验,不过我们在使用过程中也遇到了一些问题,并且在预期时间内这些问题无法被官方版本解决,因此,我们决定在 Yapi 之上做一些改造,以满足我们当前的使用场景。我们会用系列文章聊聊我们的改造和优化详细内容。