前端驱动的接口数据检查、文档生成、mock 以及接口自动化测试

咱们项目开发时,时常面临这样的问题,在接口对接时,先后端脱钩,并行开发时相互限制拖慢开发效率。以往,这件事经常是后端主导的,后端同窗输出的接口不能知足前端需求,这也是为何 graghql 火起来的缘由。如何去优化这个场景呢?通过一段时间的探索以后,最终我找到了以下的解决方案,在这个方案中,有前端同窗来主导这个过程。经过这个方案,但愿和广大开发者共同思考这一问题。html

你能够在这里阅读到详细的文档。前端


数据类型检查、文档、mock以及测试node

类型模块

利用 tyshemo 撰写项目中须要作类型检查的类型文件,通常,一个 *.type.js 中包含了多个类型容器,这些容器都对应了本身的数据结构,以及每一个节点上的值的类型。在抛开其余全部相关环节以外,类型模块在前端代码中的做用就是作数据结构、节点类型检查的。git

import { BookType } from './book.type.js'

class Book extends Component {
  request() {
    this.props.request().then(data => {
      Ty.expect(data).to.match(BookType)
      // ...
    })
  }
}复制代码

在传统架构中,将数据类型前置到 data service 中,当数据回来的时候就当即作数据检查,是一种常见方案:github

BookService.get = (id) => CommentService.request('GET', '/book/' + id).then(data => {
  Ty.trace(data).by(BookType).catch(error => console.error(error)) // 异步校验,避免带来性能损耗
  return data
})复制代码

类型模块规定了一个数据的结构,在上面的这个例子中,也就对应了一个接口的返回结果。数据库

import { Dict, Positive } from 'tyshemo'

export const BookType = new Dict({
  name: String,
  price: Positive,
})复制代码

既然有了接口的数据结构,及其类型,那么咱们是否能够生成出该接口的文档?express

文档服务

当咱们有了类型容器以后,咱们也能够将这些类型容器的内容,格式化为描述语言性质的文档。例如上面的 BookType 能够格式化为:后端

{
  name: string,
  price: positive,
}复制代码

这是一段纯文本,可是它很是清晰的描述了一个对象的全部。那么,咱们就须要有一个服务来整合接口文档所须要的东西。浏览器

一个接口的文档描述中,须要包含以下信息:bash

  • 接口别名
  • 接口描述
  • 接口的请求类型
  • 接口的 URL
  • 接口的请求参数及其类型
  • 接口的返回结构及其类型
  • 接口的错误及错误码表

那么,咱们在配置文档服务的时候,针对单个接口,咱们就要把上面这些信息所有配置进去。

{
  name: '接口1',
  description: '该接口用于获取用户信息',
  method: 'get',
  path: '/users/:id',
  request: RequestType, // 一个类型容器,用于校验请求参数是否符合类型和结构
  response: ResponseType, // 一个类型容器,用于校验响应体的类型和结构
  errorMapping: { // 一个 mapping 表,用于列出全部错误 code 值码
    10001: '数据库链接错误',
  }, 
}复制代码

其中 method 和 path 须要按照 expressjs 的路由格式来处理,由于咱们在后面须要用到它们。另外,咱们想要起一个文档服务,咱们可能还须要对字段进行备注,这时,我找到一种方法,就是在 ResponseType 上挂载一个 __comments 属性来添加备注信息:

ResponseType.__comments = {
  'name': '书名',
  'price': '价格',
}复制代码

可是,这种方式实际上是很差的,由于这样就把备注和源码分开了,可是,实际上,咱们但愿在源码中经过注释进行备注。目前我尚未找到运行时的方法去解决这个问题,想到的方案是编译时经过工具去提取备注,但还未实现。

有了文档服务,那么先后端同窗,就能够对照文档,按照约定进行开发。

Mock 服务

但文档并不能解决运行时的问题。前端开发到必定阶段的时候,必定要与接口去联调,有了接口以后,才能进行下一步的操做。这种状况下,咱们须要一个 mock 服务,在后端没有开发完时,能够前端先 mock,完成开发的大部分事情。

既然咱们有了文档,咱们发现,文档服务的配置中会规定 method、path 两项,咱们就能够利用它们,结合 express 框架,起一个本地服务器。另外就返回的数据,咱们有了对应的类型容器,可不能够在类型容器的基础上生成 mock 数据?固然能够。

例如,咱们能够将 number 生成一个随机数,能够将 string 生成一个随机字符串,而且经过随机因子,实现 boolean、ifexist 等不一样状况下值可能不一样的效果。

经过一系列的处理以后,咱们只须要利用配置信息,就能够对全部的接口进行 mock,当前端向 mock 服务接口发请求的时候,返回 mock 数据。前端最好本身起一个 node 服务,经过代理的形式,拦截本来往正式的后台接口发请求的路径,将请求转发到 mock 服务上去。

测试服务

如今,咱们将视角转移到后端的同窗身上,咱们切换身份,如今你是后台开发的同窗。在对照文档开发过程当中,你可能并不知道本身写的接口是否正常工做,可是前端的同窗不可能跟着你去进行测试。你可能会选择使用 postman 来发送假请求,这样作是能够的。可是,你须要每次都去假造请求数据,这一点比较麻烦。

在前文中,咱们配置了请求时发送的数据类型容器,那么,有没有办法经过这个容器,生成一个随机的请求数据呢?固然是能够的,和 mock 服务生成随机数据同样,咱们以 request 配置为基础,生成一个请求参数,并经过 method、path 等配置,完成模拟请求。经过这些模拟请求,就能够判断本身写的接口是否正常工做。

此外,咱们再为测试服务加上自动化测试的功能。

因为在大部分状况下,后台登录都须要浏览器窗口记录登录状态,所以,我将测试服务设计为前端浏览器能力,而非后台的测试平台。经过一个虚拟的定时任务,反复的构造假数据向后台接口发送请求,以此来统计请求成功和失败的数量。在测试阶段,这也会有帮助。

统一维护类型

前端对这些类型具备强依赖,类型文件会被直接使用到前端代码中,用来做为运行时的类型检查。(可是在产品阶段这不是必须的,能够经过工具,将类型检查代码从原始代码中去掉。)所以,维护类型文件的主要工做是前端。可是,这并不表明前端同窗能够任意修改类型文件,修改类型文件意味着对服务端返回结果的修改,但若是在后台同窗未知情的状况下这样作,最终会出问题。固然,因为有了上述三个服务的保证,这个问题通常能够在开发阶段就反馈出来。

后台的同窗,也能够参与到类型文件的维护中。在真实场景中,前端同窗主要维护请求相关的接口类型文件,然后端同窗主要维护提交接口的类型文件。

经过 git 管理类型文件,设置 hook,当类型文件更新以后,触发 CI 任务,将新的类型文件部署到服务器上,这样就能够完成上述 3 个服务的同时更新。

小结

本文基于 TySheMo 体系去解决接口的数据类型、Mock 等问题,是出于对实际工做中需求的思考,力求将整个解决方案作到最小化,轻量化,随时可抛弃,而不影响原有的业务逻辑。固然,这里面还有一些问题还没有解决,若是你有兴趣,能够参与到该项目中,一块儿改进它。

相关文章
相关标签/搜索