前后端分离模式下,我们是这样管理接口的

5,723 阅读8分钟

简介:本文分析了前后端分离开发模式下,由于接口交互,导致的前后端不能同步开发的问题,以及提出了一种综合解决方案,优化接口交互流程,提高开发效率。

目前,随着 MVVM 框架的广泛应用,前后端分离的开发模式越来越得到广大开发者的青睐。前后端分离开发,就是后端人员负责写后台业务逻辑,前端人员通过 webpack 等打包工具,开发前端页面,两者通过接口来交换数据。页面由前端根据接口数据来进行渲染,而不是通过后端来渲染。

这种开发模式,可以使前后端并行开发,各司其职,既提高了项目总体的开发效率,也让不同的角色发挥自己的特长,前后端人员更专注于自己的职责,项目总体质量也能得到提高。

前后端通过接口交互,有哪些问题?

问题 1:依赖后端接口,前端无法独立开发

分离后,前后端沟通的最重要一个环节是接口交互。假定有一个需求,开发一个显示用户信息的页面。在后端提供接口之前,前端是不知道后端的接口会返回什么格式的数据,不知道以哪个字段来获取需要的数据,因此,前端无法开发页面的逻辑,特别是现在的 MVVM 框架,由数据驱动页面,在没有数据的情况下,前端工作的进度会取决于后端提供接口的进度,违背了前后端分离开发的愿景。

问题 2:后端提供接口文档,前端需要写模拟数据

在后端提供接口文档以后,假定文档定义获取用户信息的接口如下:

// 接口路径: /getUserInfo
// 接口参数:
{
  id: 123;
}
// 返回数据
{
  "name":"张三",
  "id":123,
  "role":"admin"
}

拿到上述文档后,由于此时后端还没有开发对应的接口,导致前端无法连接后端服务器,获取数据。这时候,前端为了写逻辑,由于接口无法调通,只能自己依据接口文档,构造模拟数据。等到联调阶段,还需要把构造的模拟数据删掉,这些构造的模拟数据,上线后是完全没用的,这就是一种工作量的浪费。

问题 3:后端做接口测试,需要依赖 postman 等测试工具

当后端开发,完成了一个接口后,需要对接口做接口测试。如果这时候页面还没有完成,后端只能依据接口文档,在 postman 上面构造模拟数据,然后通过 postman 调用自己的接口,查看返回的数据。通过对比返回的数据和接口文档定义的返回数据,知道自己的后端是否按照文档返回了数据。这个过程中,在 postman 上定义模拟数据是一种工作量,人眼对比数据,也是一种工作量,开发效率大大降低。

问题 4:接口是否已经完成,接口是否有问题,需要前后端频繁沟通

由于接口文档更新不及时,以及无法保证团队的每一个成员手上的接口文档都是最新版本,甚至是,实际开发过程中接口已经变化,但是没有更新文档,只是口头交流,都会导致团队成员开发或者沟通出错,导致返工的问题,甚至是引起团队矛盾:为什么接口变化了不通知我?

解决方案

接口管理平台的诞生

为了解决接口文档不能够实时更新的问题,可以开发一个接口管理平台,在平台内定义每个接口的请求体和响应体等信息,当接口需要变更时,直接在平台上面更改。同时这个平台记录每个接口的变更日志,方便回滚和查看变更了哪些内容。

如果企业内部有通讯工具,可以继承内部通讯工具,当接口被更改了之后,自动向团队成员发送通知,告知更改了哪些内容,这样,可以保证团队内所有文档都是最新的。

同时,该平台需要支持导出接口文档的功能,因为很多团队需要电子文档做备份。不过,这只是一个无关紧要的功能。这个平台应该追求一个目标:可以在这换一个平台上,完成接口的所有生命周期的管理。

接口的生命周期管理

有了接口在线管理,就可以对接口进行生命周期管理,比如这个接口是已定义阶段,还是待联调阶段,还是已完成阶段,都可以标注出来。接口的状态一目了然。

接口的模拟响应和请求

这个平台拥有了接口的所有数据,就可以依照接口的定义,返回模拟数据。这样,将所有接口部署在这个平台上,生成一个模拟的 baseurl,前端工程将所有接口请求反向代理到这个地址,就可以获取到模拟数据,并进行相应逻辑的开发。此时,前端在不依赖后端的情况下,就可以完成开发工作。

针对后端,如果需要测试自己的接口,可以在页面上点击测试按钮,由浏览器发送请求,平台显示响应的数据。同时,因为接口平台已经有了返回数据的定义,获取到实际接口数据后,接口管理平台可以进行结构对比,并给出提示,这样,后端同学就很容易知道自己的接口到底对不对了。

跨域问题的解决

针对上文提出的接口模拟请求,是有一个问题的,当用户在接口管理平台上点击测试时,如果页面直接请求用户的服务器,会存在跨域问题。

一种解决方案是,页面将请求数据发送给接口管理平台的后台服务器,由后台服务器代为发送请求,然后,将获取到的数据返回给页面,在用户感知上,是页面直接发送了请求。

但是,虽然上述方案规避了跨域问题,但是没法获取到目标服务器的 cookie,导致依赖 cookie 的 web 程序,可能出现问题。

这就引出了另外一种方案:chrome 插件。

chrome 插件的应用

上文提出,当用户在 A 系统页面上发送请求时,无法读取 B 系统里面的 Cookie,可能导致系统运行出错。

有没有一种方案,可以获取到所有系统的 cookie 呢?答案是有的,就是使用 chrome 插件。

chrome 插件是对浏览器功能的扩展,允许用户自己编写插件,对 chrome 功能进行扩充,同时,chrome 插件不存在跨域问题,它可以读取到任何页面的任何信息。对于 chrome 插件的开发,这里不做赘述。

因此,我们可以开发一个 chrome 插件,当用户点击测试按钮是,由插件代为发送请求,插件获取到响应数据后,将数据返回给页面展示。

至此,还剩下最后一个问题:接口联调。

接口联调

当前后端开发完成以后,需要进行前后端联调,通常这时候,需要前端直连后端的服务器,或者前端将页面打包给后端进行部署,费时又费力,而且,这得建立在所有接口已经开发完的情况才能这样做,否则页面很容易就报接口错误。

既然我们已经维护了接口状态,那么我们就可以在接口管理平台上做接口联调。

比如,我们在接口管理平台上管理了接口 A,它的信息如下:

// 接口路径: /getUserInfo
// 接口参数:
// 反向代理地址: http://xx.com(该地址为接口管理平台生成的地址)
// 后端服务器地址: http://back.com(该地址为后端同学的服务器地址)
{
  id: 123;
}
// 返回数据
{
  "name":"张三",
  "id":123,
  "role":"admin"
}

工作流如下:

  1. 前端工程反向代理到 xx.com

  2. 前端请求接口: /getUserInfo,并发送数据{id:123}

  3. 接口管理平台接到前端工程的请求,匹配到对应的接口,并查询接口状态

  4. 如果接口状态为待开发阶段,则查询定义的模拟数据,并返回该数据。即,返回以下数据:

    
    {
      "name":"张三",
      "id":123,
      "role":"admin"
    }
    
  5. 如果接口状态为已完成阶段,则由接口管理平台转发该请求到http://back.com(后端同学的地址),接口管理平台获取到数据后,将数据返回给前端工程,包括请求头部等信息。

至此,整个流程已经走通。

现状

目前,多家公司推出了自己的接口管理工具,但是,每一家公司的产品或多或少有些不完善的地方,对此,我做了一些调研,供大家参考:

竞品对比.png