前后端协议制定的争论“如何平衡原子与接口封装”

1,168 阅读5分钟

近期遇到一些问题,就是后台作为服务,抽离了非常原子的操作,而 biz 层只负责了透传服务,导致前端耦合了很多业务拼装以及多请求情况。那么本篇文章就来着重分析,应该如何来更优雅的处理这类问题。

问题根源

为了减少耦合并且独立管理以及后续扩容等的方便,后台一般会把业务抽离的非常原子化,特别是底层服务。比如我们常见的一个推荐列表,那么其中就可能有这些原子服务:

  1. 推荐接口,获取推荐的 id 列表;
  2. 通过 id 获取的详情信息;
  3. 通过 id 获取的评论信息;
  4. 等等,其他原子化操作...

那么你的架构模式可能是这样的。

biz问题.jpg

带来的问题

我们先来假设没有任何的 biz 层,这些原子服务都是由前端来处理的,可想而知前端需要处理的耦合情况会有多严重。这样带来的问题,我举个简单例子,后台需要修改获取评论信息的接口,由原来的 2 个参数,修改为 3 个,但是整体页面和数据展示结构都不变。但是这时候开发会告诉你,会有兼容性问题,以前的旧版本将不支持这样的数据,作为产品你就会很懵逼,我只是修改了数据获取方式,为什么会有前端的关系呢?

这时候你要拉上你的 leader 详细的表述一遍,如果是 WEB 倒也还好,如果是客户端就很麻烦了。

解决方案

这种场景就需要有一个 biz 层(bff 层),通过 biz 层来收拢接口请求,我们把上面的架构进行调整,增加一个 biz 层来处理,就比如下面的方面。

biz问题2.jpg

前端只需要请求一个接口叫做获取推荐列表,biz 层来组合多个服务的基础信息,并按照前端的数据结构要求进行返回。

带来的问题

上面的方案对前端来说是非常舒服了,但是对于后台的 biz 层来说性能是一个非常大的问题,这么多接口只要有一个接口慢,就可能导致整个数据获取变慢,从而影响用户体验。特别是一种问题,比如我们拉取首页接口,假设首页包含这些模块:

  1. 首页 icon ;
  2. 运营位信息,比如说 banner;
  3. 新人模块信息;
  4. 推荐列表;

假设这些都由后端来组织生成,那么势必会导致这个界面最终出来的效果很慢,比如说推荐接口会比较慢,那么所有的信息显示都非常慢,影响用户体验。那么怎么解决这类问题呢?

其次还会带来一个非常严重的问题就是请求被放大,假设我们请求的是一个页面接口,但是由于调用了多个请求,导致最终请求被放大。

性能解决

根据上面的问题,我们首先要做的是区分前端部分的核心与非核心模块。比如我们 APP 核心是首页 icon ,又比如歌曲详情是歌曲播放相关功能,又比如商品详情是商品的定价以及优化相关信息,再比如直播的核心是直播画面播放。

那么这时候我们只需要把核心接口抽离。

  • APP 首页,抽离出首页 icon 接口;
  • 歌曲详情,抽离出获取歌曲播放的地址接口以及部分歌曲展示必要的详情,例如 title以及封面;
  • 商品详情,抽离出获取商品必要的 title 以及图片,同时抽离出价格展示以及优惠券接口;
  • 直播房间,抽离出获取直播播放接口的地址以及直播的 title 信息等。

抽离完成后,再按照接口是否可缓存来分析。

  • 可缓存的,与用户关联不大,或者可按照用户群体进行缓存的,大部分人都是获取相同信息的,比如首页 icon,歌曲的播放地址,直播房间的下行地址等等。
  • 不可缓存的,例如推荐相关服务,或者个性化相关的,比如用户个人的优惠券列表,个人的历史等等。

按照可缓存与不可缓存抽离后,再来分析可缓存部分

  • 可定时缓存,这种类似于运营配置好,直接定时生成的配置,这种直接走这种定时缓存即可。
  • 访问缓存,这种类似于需要单个用户请求后,再缓存的数据,这部分需要注意缓存穿透的问题。
三个重点

核心接口,独立接口,独立模块

接口按照缓存与不可缓存划分,提升业务稳定性和性能

缓存需要根据定时缓存和访问缓存来划分

总结

因此前后端划分接口时,不是一家之言,需要根据多方面业务的不同进行接口划分,也不是一个接口解决一个页面,需要大家多进行沟通和交流,按照最合适的角度去定义接口。其次定义接口协议,也不是后台确定就行的,需要前后端一起来讨论。

上面的协议制定,都是基于一个核心,那就是 biz 层(bff 层)必须存在,并且一定不是简单的透传。