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

广告位招租
扫码页面底部二维码联系

我们项目开发时,时常面临这样的问题,在接本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。口对接时,前后端脱钩,并行开发时相互限制本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】拖慢开发效率。以往,这件事常常是后端主导【本文首发于唐霜的博客】【转载请注明来源】的,后端同学输出的接口不能满足前端需求,著作权归作者所有,禁止商业用途转载。【转载请注明来源】这也是为什么 graghql 火起来的原【本文受版权保护】【关注微信公众号:wwwtangshuangnet】因。如何去优化这个场景呢?经过一段时间的【作者:唐霜】【本文首发于唐霜的博客】探索之后,最终我找到了如下的解决方案,在【版权所有,侵权必究】【版权所有,侵权必究】这个方案中,有前端同学来主导这个过程。通著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。过这个方案,希望和广大开发者共同思考这一著作权归作者所有,禁止商业用途转载。【作者:唐霜】问题。

【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。【本文受版权保护】

数据类型检查、文档、mock以及测试【作者:唐霜】

【作者:唐霜】本文作者:唐霜,转载请注明出处。原创内容,盗版必究。

类型模块【作者:唐霜】

【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。本文作者:唐霜,转载请注明出处。

该模块用于撰写项目中需要做类型检查的类型【原创不易,请尊重版权】【版权所有,侵权必究】文件,一般,一个 *.type.js 中著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】包含了多个类型容器,这些容器都对应了自己【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。的数据结构,以及每个节点上的值的类型。在【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】抛开其他所有相关环节之外,类型模块在前端未经授权,禁止复制转载。【未经授权禁止转载】代码中的作用就是做数据结构、节点类型检查本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。的。

原创内容,盗版必究。【未经授权禁止转载】【原创不易,请尊重版权】
import { BookType } from './book.type.js'

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

在传统架构中,将数据类型前置到 data转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net service 中,当数据回来的时候就【本文受版权保护】【版权所有,侵权必究】立即做数据检查,是一种常见方案:

【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。
BookService.get = (id) => CommentService.request('GET', '/book/' + id).then(data => {
  Ty.trace(data).by(BookType).catch(error => console.error(error)) // 异步校验,避免带来性能损耗
  return data
})

类型模块规定了一个数据的结构,在上面的这原创内容,盗版必究。转载请注明出处:www.tangshuang.net个例子中,也就对应了一个接口的返回结果。

【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。
import { Dict, Positive } from 'tyshemo'

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

既然有了接口的数据结构,及其类型,那么我转载请注明出处:www.tangshuang.net【未经授权禁止转载】们是否可以生成出该接口的文档?

【原创不易,请尊重版权】【本文首发于唐霜的博客】【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】

文档服务【作者:唐霜】

【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。

当我们有了类型容器之后,我们也可以将这些本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。类型容器的内容,格式化为描述语言性质的文本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。档。例如上面的 BookType 可以格原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。式化为:

【本文受版权保护】原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】
{
  name: string,
  price: positive,
}

这是一段纯文本,但是它非常清晰的描述了一【转载请注明来源】【作者:唐霜】个对象的所有。那么,我们就需要有一个服务著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】来整合接口文档所需要的东西。

【原创内容,转载请注明出处】【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。

一个接口的文档描述中,需要包含如下信息:

【作者:唐霜】【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】
  • 接口别名【关注微信公众号:wwwtangshuangnet】
  • 原创内容,盗版必究。本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。
  • 接口描述【访问 www.tangshuang.net 获取更多精彩内容】
  • 【作者:唐霜】【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。
  • 接口的请求类型未经授权,禁止复制转载。
  • 【关注微信公众号:wwwtangshuangnet】【作者:唐霜】【本文受版权保护】
  • 接口的 URL本文版权归作者所有,未经授权不得转载。
  • 【未经授权禁止转载】转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net
  • 接口的请求参数及其类型【关注微信公众号:wwwtangshuangnet】
  • 【本文受版权保护】本文作者:唐霜,转载请注明出处。【转载请注明来源】原创内容,盗版必究。【版权所有,侵权必究】
  • 接口的返回结构及其类型【版权所有,侵权必究】
  • 本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net【未经授权禁止转载】【本文首发于唐霜的博客】
  • 接口的错误及错误码表本文版权归作者所有,未经授权不得转载。
  • 本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】

那么,我们在配置文档服务的时候,针对单个转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】接口,我们就要把上面这些信息全部配置进去未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net

【版权所有,侵权必究】【作者:唐霜】【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。
{
  name: '接口1',
  description: '该接口用于获取用户信息',
  method: 'get',
  path: '/users/:id',
  request: RequestType, // 一个类型容器,用于校验请求参数是否符合类型和结构
  response: ResponseType, // 一个类型容器,用于校验响应体的类型和结构
  errorMapping: { // 一个 mapping 表,用于列出所有错误 code 值码
    10001: '数据库连接错误',
  }, 
}

其中 method 和 path 需要按【本文受版权保护】未经授权,禁止复制转载。照 expressjs 的路由格式来处理【关注微信公众号:wwwtangshuangnet】【作者:唐霜】,因为我们在后面需要用到它们。另外,我们【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】想要起一个文档服务,我们可能还需要对字段【访问 www.tangshuang.net 获取更多精彩内容】【作者:唐霜】进行备注,这时,我找到一种方法,就是在 本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.netResponseType 上挂载一个 _未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net_comments 属性来添加备注信息:

【未经授权禁止转载】【转载请注明来源】【原创内容,转载请注明出处】【本文首发于唐霜的博客】
ResponseType.__comments = {
  'name': '书名',
  'price': '价格',
}

但是,这种方式其实是不好的,因为这样就把【转载请注明来源】【版权所有,侵权必究】备注和源码分开了,但是,实际上,我们希望本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】在源码中通过注释进行备注。目前我还没有找【作者:唐霜】本文作者:唐霜,转载请注明出处。到运行时的方法去解决这个问题,想到的方案原创内容,盗版必究。【转载请注明来源】是编译时通过工具去提取备注,但还未实现。

本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】

有了文档服务,那么前后端同学,就可以对照【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。文档,按照约定进行开发。

原创内容,盗版必究。【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】

Mock 服务【关注微信公众号:wwwtangshuangnet】

【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net【作者:唐霜】

但文档并不能解决运行时的问题。前端开发到【转载请注明来源】【原创不易,请尊重版权】一定阶段的时候,一定要与接口去联调,有了本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。接口之后,才能进行下一步的操作。这种情况原创内容,盗版必究。【本文受版权保护】下,我们需要一个 mock 服务,在后端【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net没有开发完时,可以前端先 mock,完成【版权所有,侵权必究】【原创不易,请尊重版权】开发的大部分事情。

【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。【作者:唐霜】

既然我们有了文档,我们发现,文档服务的配【作者:唐霜】【本文首发于唐霜的博客】置中会规定 method、path 两项【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】,我们就可以利用它们,结合 expres转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。s 框架,起一个本地服务器。另外就返回的【版权所有,侵权必究】【作者:唐霜】数据,我们有了对应的类型容器,可不可以在【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。类型容器的基础上生成 mock 数据?当原创内容,盗版必究。【本文首发于唐霜的博客】然可以。

【作者:唐霜】转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】

例如,我们可以将 number 生成一个【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net随机数,可以将 string 生成一个随【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。机字符串,并且通过随机因子,实现 boo未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。lean、ifexist 等不同情况下值本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。可能不同的效果。

【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】【转载请注明来源】

通过一系列的处理之后,我们只需要利用配置原创内容,盗版必究。转载请注明出处:www.tangshuang.net信息,就可以对所有的接口进行 mock,【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。当前端向 mock 服务接口发请求的时候【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。,返回 mock 数据。前端最好自己起一【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。个 node 服务,通过代理的形式,拦截【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net原本往正式的后台接口发请求的路径,将请求未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net转发到 mock 服务上去。

【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】【版权所有,侵权必究】

测试服务【作者:唐霜】

【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。【转载请注明来源】【本文首发于唐霜的博客】【本文受版权保护】

现在,我们将视角转移到后端的同学身上,我【未经授权禁止转载】【本文首发于唐霜的博客】们切换身份,现在你是后台开发的同学。在对原创内容,盗版必究。未经授权,禁止复制转载。照文档开发过程中,你可能并不知道自己写的【转载请注明来源】【本文受版权保护】接口是否正常工作,但是前端的同学不可能跟【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】着你去进行测试。你可能会选择使用 pos【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.nettman 来发送假请求,这样做是可以的。转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。但是,你需要每次都去假造请求数据,这一点转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net比较麻烦。

著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。转载请注明出处:www.tangshuang.net【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】

在前文中,我们配置了请求时发送的数据类型【作者:唐霜】【本文受版权保护】容器,那么,有没有办法通过这个容器,生成未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。一个随机的请求数据呢?当然是可以的,和 【关注微信公众号:wwwtangshuangnet】【本文受版权保护】mock 服务生成随机数据一样,我们以 【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】request 配置为基础,生成一个请求【本文受版权保护】未经授权,禁止复制转载。参数,并通过 method、path 等【转载请注明来源】【未经授权禁止转载】配置,完成模拟请求。通过这些模拟请求,就【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。可以判断自己写的接口是否正常工作。

【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】

此外,我们再为测试服务加上自动化测试的功未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net能。

本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】

由于在大部分情况下,后台登陆都需要浏览器本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】窗口记录登陆状态,因此,我将测试服务设计著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net为前端浏览器能力,而非后台的测试平台。通【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。过一个虚拟的定时任务,反复的构造假数据向【本文受版权保护】转载请注明出处:www.tangshuang.net后台接口发送请求,以此来统计请求成功和失【本文受版权保护】【版权所有,侵权必究】败的数量。在测试阶段,这也会有帮助。

本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net

统一维护类型【访问 www.tangshuang.net 获取更多精彩内容】

【本文首发于唐霜的博客】【版权所有,侵权必究】原创内容,盗版必究。原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】

前端对这些类型具有强依赖,类型文件会被直【本文受版权保护】【版权所有,侵权必究】接使用到前端代码中,用来作为运行时的类型著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】检查。(但是在产品阶段这不是必须的,可以本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】通过工具,将类型检查代码从原始代码中去掉【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。。)因此,维护类型文件的主要工作是前端。未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。但是,这并不代表前端同学可以任意修改类型【原创不易,请尊重版权】【版权所有,侵权必究】文件,修改类型文件意味着对服务端返回结果【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】的修改,但如果在后台同学未知情的情况下这著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。样做,最终会出问题。当然,由于有了上述三【原创内容,转载请注明出处】【本文受版权保护】个服务的保证,这个问题一般可以在开发阶段【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。就反馈出来。

【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net

后台的同学,也可以参与到类型文件的维护中【本文受版权保护】【本文首发于唐霜的博客】。在真实场景中,前端同学主要维护请求相关【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net的接口类型文件,而后端同学主要维护提交接【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net口的类型文件。

未经授权,禁止复制转载。【本文首发于唐霜的博客】【本文首发于唐霜的博客】

通过 git 管理类型文件,设置 hoo本文版权归作者所有,未经授权不得转载。【本文受版权保护】k,当类型文件更新之后,触发 CI 任务【作者:唐霜】本文版权归作者所有,未经授权不得转载。,将新的类型文件部署到服务器上,这样就可【作者:唐霜】【版权所有】唐霜 www.tangshuang.net以完成上述 3 个服务的同时更新。

未经授权,禁止复制转载。【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。【转载请注明来源】

小结【本文首发于唐霜的博客】

【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】

本文基于 TySheMo 体系去解决接口【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】的数据类型、Mock 等问题,是出于对实转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net际工作中需求的思考,力求将整个解决方案做本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net到最小化,轻量化,随时可抛弃,而不影响原【版权所有,侵权必究】【原创内容,转载请注明出处】有的业务逻辑。当然,这里面还有一些问题尚【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】未解决,如果你有兴趣,可以参与到该项目中【版权所有】唐霜 www.tangshuang.net,一起改进它。【转载请注明来源】

【转载请注明来源】本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【未经授权禁止转载】

2019-09-29 4566

为价值买单,打赏一杯咖啡

本文价值45.66RMB