BFF初探

1

一、当前开发遇到的常见“痛点”

在前后端联调时,有些麻烦出现的频率不低而且可能会较大程度影响开发效率,其中就包括前后端对接口数据格式设计的差异。两者一是基于领域模型,一是基于用户交互,因此设计出来的数据结构经常有差异,使得前端从接口取到数据后还需要多做一层“数据规格化”(我自己的称呼…)的工作。举两个例子:

命名习惯不一致,例如有这样的一个列表数组ranks:

[

{
    id: 1,
    value: 'DUCHY'
},
{
    id: 2,
    value: 'KINGDOM'
},
{
    id: 3,
    value: 'EMPIRE'
}

]
页面的渲染组件需要value这一属性名,但接口数据使用的是name,那么就需要做一个遍历,手动修改属性名。

类似的情况还有(null、’’)/([]、{})的转换等等,这都是为了数据格式所做的额外操作,与业务逻辑并没有太大关联。

为复用某些接口,需要做一些接口数据额外处理:

数据对象info:

{

countries: [
    {
        name: 'Austria',
        cities: [
            'Vienna',
            'Tirol'
        ]
    },
    {
        name: 'Persia',
        cities: [
            'Isfahan',
            'Shiraz'
        ]
    },
    {
        name: 'United States',
        cities: [
            'San Francisco',
            'Mountain View'
        ]
    }
]

}
现在有一个场景,我只想要countries数组的第一项(或者说,在特定场景下只有第一项是有意义的),那么我如果复用这一接口拿到的数据,每次就都要做一个let specifiedCountry = countries[0]的默认赋值,在更复杂的场景下这种赋值可能嵌套更深、重复次数更多。

显然,处理数据格式与处理交互时的数据变化应该分离,这样前端会有更多精力去处理交互的业务逻辑。

二、对GraphQL的探索及其应用

要应对这一需求,当下的GraphQL是一个不错的方案,用它可以做到指定一个请求格式,然后获取所需的数据,同时它也支持一些逻辑判断和抽象,如directive、Fragment、Variable等等,以下取这三个作为例子,演示一下对于上述例子的解决方案:

对于(一)中的第一个例子:

考虑GraphQL的alias解决方案:GraphQL的别名alias设计目的是在同一个Type下可以返回多个对象而不发生命名冲突,不过我们也可以用它做一下name -> value 的重命名:

ranks {

id
value: name

}
*嵌套的别名是否可行未知,还需要做一下验证

对于(一)中的第二个例子:

使用variable和directive做一些逻辑处理:

query Country($isFirst: Boolean!) {

info(episode: $episode) {
    countries @include(if: $isFirst) {
        name
        cities
    }
}

}
数据模型中,第一个元素包含isFirst: true即可(这里可能还要深究一下,isFirst如何设置才能真正解决原来的问题,或者说需要别的判断方式)

三、BFF的定位及node.js在BFF层能做的事情

BFF的应用场景有很多,聚合后端接口,提供给第三方api都是它可以负责的工作。聚合后端接口在上文已经有了类似的操作,不过做的不是聚合几个接口而是对某个接口做了额外处理。

BFF层的设计一般来说可以更好地满足产品快速迭代的需求,因为它将UI交互与部分服务都交给了一个team(可以是Frontend)负责,这样可以大大减少不同team的沟通协调成本。

node.js也可以做一部分在BFF层的数据加密(放BFF层合适吗?)、请求转发(需要和nginx做一下对比)

也可以做一些性能优化的工作(依然要对比以往服务端的解决方案)

性能优化
高并发与负载均衡:常见的情况下,高并发的性能制约包括了大量的I/O操作时CPU利用率较低,而node.js在处理I/O密集型操作时有自己的优势。

在负载均衡方面,nginx有几套常用的请求分配方案,也有shared memory的解决方案,并且在保证会话一致性上有较好的表现。

node.js的clientRequest对象也会维护一个header queue,可以对请求的流程做一定的控制。

你可能感兴趣的

载入中...