Skip to content

Latest commit

 

History

History
148 lines (99 loc) · 7.68 KB

2.md

File metadata and controls

148 lines (99 loc) · 7.68 KB

本地化接口模拟、前后端并行开发

1. 为什么需要 “本地化接口模拟、前后端并行开发”

在前后端分离之前,前后端的数据交流以及页面渲染使用后端的模板(如 java > jspphp > smarty)是很常见的,所以前端对页面的开发与调试总是依赖后端程序,而不能本地运行,这就导致前端开发很耗时,并且毫无意义。前后端分离之后,前端能够在本地运行服务程序、开发、调试,这让前端开发人员从与后端耦合开发的过程中解脱出来,更高效快捷的开发 web 前端程序。基于此,我们便有了“本地化接口模拟”的需求。

2. 本地化接口模拟

这就是说我们要在本地模拟一个与服务器差不多的环境,能够提供数据所需的接口,进行错误模拟处理等等。

一般来说,本地数据模拟的解决方案有两种思路:

  1. 同等模拟服务器环境,就是依据文档,完全按照服务器的接口配置搭建本地的接口服务;
  2. 多环境配置&切换,就是从代码的层面配置多个环境(如 线上环境,本地环境),根据是在线上还是在本地切换不同的环境。

2.1 同等模拟服务器环境

这种方式基本上不需要在代码层面做更改,因为本地接口与服务器接口基本上一致,包括接口名称,请求方法,请求参数,响应数据。

这种思路的解决方案很多,比较典型的有:

基于 YAML,帮助设计 RESTful API 和鼓励对 API 的发掘和重用,解析并自动生成对应的客户端调用代码、服务端代码 结构, API 说明文档。

这个工具强能很强大,本地化接口模拟只是其中的一个功能。

基于 JSON 进行文档定义的一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。

也是一个功能很强大的工具,本地化接口模拟也只是其中的一个功能。与 RAML 相比,RAML 解决的问题是设计阶段的问题,而 Swagger 则是侧重解决现有 API 的文档问题,它们最大的不同是 RAML 需要单独维护一套文档,而 Swagger 则是通过一套反射机制从代码中生成文档,并且借助 ajax 可以直接在文档中对 API 进行交互。

基于 Markdown 的一套 API 描述标准,使用工具可以把标记文稿转换成漂亮的接口文档,并提供本地化接口模拟功能。

因为是基于 Markdown,所以使用门槛比前两者低了很多,但功能不及前两者强大。

2.2 多环境配置&切换

这种方式是在代码的层面配置多个环境(如 线上环境,本地环境),根据是在线上还是在本地切换不同的环境。

比如,开发的时候切换到本地环境,线上运行的时候切换到线上环境(如果有需要,可以配置更多环境)。在本地环境接口都是采用的本地化模拟的接口,而线上环境接口则是线上实际运行的接口。这样做的好处是:

  • 可以把应用对接口的实现进行一次封装隔离,如此,如果接口有任何改动,我们只需要改封装隔离的代码,而不需要动其他地方的代码,这在大型应用中尤为突出;
  • 能够更好的管理代码,并且一目了然当前页面有多少接口,更具可读性和移植性。

未封装隔离的实现(以 jQuery.ajax 为例):

// file1.js
$.getJSON('/api/v1/home/index/list', {keyA: 'valueA', keyB, 'valueB'}, res => {...});

// file2.js
$.getJSON('/api/v1/home/index/add', {keyC: 'valueC', keyD, 'valueD'}, res => {...});

...

如果应用比较小,接口实现比较少,其实也没什么问题,但如果是复杂应用中,当接口名称、请求方法、请求参数或返回数据字段发生变化,这个时候就需要到处去找使用的地方,然后到处改。这个时候就需要对接口进行封装隔离了。

对接口进行封装隔离,以 see-ajax(对 ajax 的封装), see-fetch(对 fetch 的封装) 为例:

// ajax1.js (0:线上环境,1:本地环境)
seeAjax.config('list', {
    method: [
        'post' // 线上环境使用 post 方法,本地使用默认的 get 方法
    ],
    stringify: [
        true  // 线上环境序列化请求参数
    ],
    settings: [
        // 自定义 ajax 配置
    ],
    url: [
        'online url',
        'local url'
    ],
    requestKeys: [
        {
            keyA: 'keyF' // 线上环境下把请求 {keyA: 'valueA'} 映射成 {keyF: 'valueA'}
        }
    ],
    responseRefactor: [
        // json 格式化
    ],
    preHandle: [
        // 请求发出之前对本次请求参数的更多操作,如添加、修改
    ],
    postHandle: [
        // 响应之后的操作
    ],
    implement: [
        // 自定义实现接口
    ],
    implementDelay: [...] // milliseconds delay for implement
});


// file1.js
seeAjax('list', {keyA: 'valueA', keyB, 'valueB'}, res => {...});

...

这样做,即使接口有变化,只需要改 ajax1.js 文件中对名为 list 请求的配置(包括请求方法,是否序列化请求参数,重定请求键名,格式化响应数据等等),而不需要改其他调用这个接口的地方。

2.3 两者配合使用

本地化接口模拟这两种方式是从不同的角度出发给出的解决方案,可以配合在一起使用。

3. 前后端并行开发

正常情况下,前端的开发在完成 UI 或者组件开发之后,就需要等后端给出接口文档才能继续进行,这对项目无疑是延长了开发周期,所以如果能做到前后端并行开发,就比较完美了。

前后端并行开发,就是说前端的开发不需要等后端给出接口文档就可以进行开发,等后端给出接口之后,再对接好后就基本上可以上线了。在本地化接口模拟的实现下,我们就可以做到前后端并行开发了。

还是以 see-ajax, see-fetch 为例:

开发过程中预定 3 个环境:0(线上环境),1(本地模拟后台接口环境),2(并行开发环境)

  • 并行开发环境:并行开发的时候,预定好自己想要的接口,需要传给后端的请求参数,以及需要的响应数据;
  • 本地模拟后台接口环境:与后台对接的时候,开启本地模拟后台接口环境,通过对请求进行配置,给到后端想要的数据,获取自己想要的数据;
    • 通过 method 配置请求方法
    • 通过 stringify 配置是否序列化请求参数
    • 通过 url 配置请求地址
    • 通过 requestKeys 配置请求参数更名
    • 通过 responseRefactor 配置对响应数据进行格式化
    • 通过 preHandle 配置请求发出之前对本次请求参数的更多操作,如添加、修改
    • 通过 postHandle 配置响应之后的操作
    • ...
  • 线上环境:一般来说对接完后要进行线上调试,此时的线上调试的工作量较之前已经大大的较低了。

4. 后续

参考文章:

  1. API 设计: RAML、Swagger、Blueprint 三者的比较

更多博客,查看 https://github.com/deepraining/blogs

作者:深雨 (@deepraining)

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证