Watcher

请求库

2021-06-09

当公司业务涉及到多端的时候,会遇到不同环境下请求库的使用方式不同的问题

001

最近为公司写了一个请求库,是基于市面上的一些请求库做的二次封装,主要是为了抹平不同请求库之间的使用差异,因为公司的业务涉及到不同的环境,包括 PC 端、移动(web)端、小程序端,为了让开发者开发体验一致,避免没必要的阅读理解成本,就需要在这些不同请求库的上面再封装一层。

基础架构

架构的角度我需要考虑两个问题,如何使用不同的请求库,和如何帮开发者解决一些业务问题。第一个问题解决起来很简单,类似 Java 开发里的接口的概念,代码中我先定义一个请求对象,所有逻辑都围绕这个请求对象展开,但这个请求对象是在不同的场景下设置进去的,我们称它为 request-core。第二个问题复杂一点,因为业务场景是未知的,在思考这个问题的时候,只能先模拟几个常见的业务问题,然后围绕这些模拟的业务问题来制定解决方案。

我们假设现在有这样几个业务场景:

  • 我需要在请求的时候可以统一设置 loading 动画
  • 我需要可以统一设置请求的公共参数
  • 我需要在请求发生错误的时候统一处理

通过分析这几个问题,我发现这几个场景是分阶段的,比如设置 loading,是在请求开始和请求结束这两个阶段发生的,设置公共参数是在请求开始前发生的,处理请求错误是在请求返回后发生的,结合这个规律我创建了一个请求生命周期,然后通过拦截器的方式暴露给用户。

requestBefore ==> requestAfter || requestFail

我也考虑过使用中间件的方式来实现这个生命周期的逻辑,但最终还是选择了拦截器,主要是考虑到中间件的概念对于普通开发者而言比较陌生,拦截器就是一些函数,理解起来比较简单。

基于这个生命周期的模型,我实现了上述这些模拟的场景,我们这里称为 request-filter,并把它通过拦截器的方式开放给开发者,开发者更具各自的场景选择使用不同的拦截器。这个设计还有一个目的,就是让其它的开发者可以在 request-filter 这个库里添加不同的拦截器来实现更过的业务场景。

产物

最终我创建了两个核心库,一个是 request-core,用于提供请求发生时不同阶段的生命周期。request-filter 用于存放解决不同业务问题的拦截器。

当然,在不同端下还会有一个请求库,比如在 PC 端,我还会创建一个 request-pc 库,它依赖 request-core 库,在这个库里给核心库设置对应环境的请求能力实现。当需要支持不同的端的时候,创建对应环境的请求库就好了。

总结

回顾我们的初始需求 “为不同端提供统一的请求库使用方式” 到这里就完成了,我们通过抽离差异、提供能力的方式解决了这个问题,并且我们还制定了持续扩展的方案用以解决后续遇到的未知问题。

遗留问题

目前的设计,不同生命周期里的拦截器最终是在一个数组里,当请求执行到对应的阶段的时候去触发这个数组里的所有拦截器,这里就出现拦截器执行先后问题

  • 拦截器先后问题

不过目前可以通过通知初始化拦截器的顺序解决这个问题,如果后续改造这里,我再更新到这里


Yang

Yang的个人博客
我在这里记录我的生活