BFF和微服务架构
首先
我是Sweeep的CTO,我最近在CADDi主辦的這場活動中進行了關於「BFF和微服務架構」的LT演講。我把當時的演講內容整理成了一篇文章。
这是我演讲的幻灯片。
以下是文章的内容。
-
- BFF和微服务架构的背景
-
- GraphQL/BFF引入的好处和挑战
- 总结和未来的挑战
1. 选择BFF和微服务架构的背景
单体化的架构
产品推出已经过去了3年,技术债务积累得相当严重。

在单一架构中存在以下问题。
-
- モノリスなアーキテクチャを同時修正でコンフリ
-
- 単一DBでデータの肥大化。マイグレーションなど大変
- 凝集度が低く修正箇所漏れ
因此,开发速度减慢和功能发布延迟是由于配置错误和技术退化所造成的。
微服务架构
因此,我们对架构进行了改进,将其转换为微服务架构。

我们通过微服务将单体架构的技术债务解决了如下。
-
- モノリスなアーキテクチャを同時修正でコンフリ
-
- → microservicesを少人数で各service修正
-
- 単一DBでデータの肥大化。マイグレーションなど大変
-
- → microservices毎にDBをもつ
-
- 凝集度が低く修正箇所漏れ
- → 適切なドメインで凝集度上げる
微服务面临的问题。
然而,微服务面临以下问题。
-
- 複数DBにおける情報の集約化
-
- ex. :支払情報とユーザ情報など別DB
-
- 複数リソースにおけるFEの工数増・肥大化
- ex. :上記支払情報にあるuser_idとユーザ情報を紐付け
因此,我们正在使用BFF来进行信息的聚合和关联,就像下面的示例一样,并使用GraphQL返回聚合信息。

除此之外,在获取信息的同时,还存在同时更新多个资源的用例。
GraphQL/BFF的引入带来的好处和挑战。
GraphQL的优点
GraphQL有以下优点:
– 微服务架构:GraphQL可以将业务逻辑分割成多个可独立部署的微服务。
– 灵活性:GraphQL可以根据客户端的需求动态获取数据,避免了不必要的数据传输。
– 强大的查询能力:GraphQL支持复杂的嵌套查询和变更操作,提供了更灵活和高效的数据查询方式。
– 高度可扩展:GraphQL允许添加新的字段和类型而无需对现有API做任何改动。
– 智能缓存机制:GraphQL可以在服务端进行智能缓存,并根据具体需求进行缓存策略的调整。
– 减少网络请求次数:由于GraphQL可以一次性获取多个数据,可减少网络请求的次数,提高性能。
-
- スキーマ駆動開発
-
- スキーマからClient/Server生成
- クエリライクで複数リクエストなしに情報を取得できる
以下我会解释关于基于架构的开发和基于架构生成客户端/服务器的内容。
基於模式驅動與模擬的並行開發。
通过使用从定义文件生成客户端和服务器程序的自动化工具进行基于模式的开发,以确保客户端和服务器之间没有差异。同时,通过基于定义文件创建模拟数据,使得即使服务器开发尚未完成,客户端也能够访问模拟数据进行通信部分的开发和功能测试。

通过GraphQL模式生成客户端/服务器
我们正在根据GraphQL模式自动生成客户端和服务器(BFF)程序,就像以下示例一样。
- Client (TS) → client/model生成
$npm run graphql-codegen --config ./path/to/config.yml
- config.yml
/schema: http://localhost:3000/graphql
documents: ./src/**/*.graphql
generates:
./src/types.ts:
plugins:
- typescript
- typescript-operations
- BFF (Go) → resolver/model生成
$go run github.com/99designs/gqlgen generate
- gqlgen.yml
schema: "*.graphql"
exec:
filename: generated.go
model:
filename: models_gen.go
resolver:
type: Resolver
layout: follow-schema
dir: .
models:
...
最好的朋友的好处 BFF
作为最好的朋友的好处有以下几点优势。
-
- 各microservicesリソースをFEの必要な情報に束ねて返す
- EndpointがBFF一箇所で済む
BFF无和BFF有的比较(信息汇总)
如果没有BFF,需要分别获取用户信息和支付信息,并在前端进行关联。
如果有BFF,可以将用户信息和支付信息捆绑在一起,这样前端就不需要进行信息聚合了。

BFF无与BFF有的比较(终点聚合)
如果没有BFF(Backend For Frontend),每个客户端都需要意识到各自的BE(微服务)。
如果有BFF,由于端点已经聚合,客户端只需向BFF发起请求即可。

GraphQL的问题
在客户端和BFF之间的通信中,我们使用GraphQL,在BFF和BE之间的通信中我们使用gRPC(Protobuf)。然而,GraphQL和Protobuf之间需要进行数值转换。
-
- Request: model.xxxInput → pb.xxxRequest
- Response:model.xxx ← pb.xxxResponse
例如,在GraphQL中只能支持int类型,但在Protobuf中,对于int32/64类型,会发生以下的用户ID值的重装。
例如,在GraphQL中只支持int类型,但是在Protobuf中对于int32/64类型,会发生以下的用户ID值的重新整理。

最好的朋友的课题
BFF这个概念也面临着以下类似的挑战。
-
- BFF開発分の工数増・メンテ増
-
- ただmicroservices → BFF → FEと透過的に情報を渡しているだけで冗長に感じることがある
- 反面、BFFでいろいろやらせる(=やらせたくなる)とFatになるので気をつける
我想也许是更好的选择让BFF关系淡化一点。
总结和未来的课题
总结:GraphQL和BFF的好处
以下是关于GraphQL和BFF优点的总结。
-
- GraphQLはスキーマ駆動・情報の集約という点でメリット
- BFFはmicroservicesの仲介役・Endpointの集約でメリット
此外,我认为在之后加入BFF是一个明智的决定,因为它有巨大的影响力。
-
- BFFの新規開発
-
- スキーマやEndpoint変更に伴うクライアント側の対応工数
- インフラや運用の追加など

未来的挑战
-
- BFF開発分の工数増で冗長に感じることも多いが、ない場合はFEで頑張らないといけなかったりする。
-
- → 次回適用する際はGraphQL Gatewayなど検討したい。
-
- GraphQL & BFFは現在Web & Mobile共通のため、同時リリース。
- → 共通化やアジリティを下げない仕組みに課題。
最后一句
我們在這次中介紹了關於BFF和微服務架構所選用的GraphQL/BFF的優點和相關問題。
我負責BFF/BE的開發,由於開發人員少,因此BFF開發的工時相當累人。但是,我們最初決定引入BFF後續的添加可能會很困難。我認為這個判斷在一定程度上是正確的。
然而,架構並沒有所謂的「銀彈」,所以我們希望能夠繼續改進。
非常感谢您阅读到这里!