Apollo GraphQL架构优化咨询:如何避免重复数据加载与传输
Apollo 栈 GraphQL 重复数据冗余优化方案
以下优化方案均不会额外增加客户端业务逻辑复杂度,可按优先级逐步落地:
1. 开启规范化缓存(投入最低,收益最高)
Apollo 全栈原生支持基于对象唯一ID的规范化能力,仅需两步即可实现同ID对象自动去重:
- 给所有Schema对象类型新增全局唯一
id字段,示例修改如下:type Group { id: ID! name: String members: [Person] } type Person { id: ID! name: String email: String avatar: Avatar follows: [Person] followedBy: [Person] contacts: [Person] groups: [Group] bookmarks: [Bookmark] sentMessages: [Message] receivedMessages: [Message] } type Message { id: ID! text: String author: Person recipients: [Person] } type Bookmark { id: ID! message: Message } - 后端返回数据时,同步返回对应对象的
id值即可,客户端Apollo Client 3及以上版本默认开启规范化缓存,会自动将同ID的对象合并存储,无论该对象出现在follows、contacts还是recipients字段下,客户端仅存一份数据,后续查询命中缓存时无需再发起请求。 - 服务端可同步开启响应缓存插件,相同请求直接返回缓存结果,减少重复业务逻辑执行与数据库查询。
2. 开启传输层压缩
在反向代理层(如Nginx)或Apollo Server中开启gzip/brotli压缩,重复结构的JSON数据在压缩后冗余率会下降70%以上,该操作属于基础设施配置,前后端业务代码无需任何修改,客户端无感知。
3. 后端接入Dataloader
后端Resolver层接入Dataloader做批量查询与单次请求内的数据缓存,同一个ID的对象在单次查询中仅会查一次数据库,既降低数据库压力,也能保证返回的同ID对象内容完全一致,进一步提升压缩效率。
4. 客户端复用查询片段
客户端可将常用的对象字段封装为GraphQL Fragment,避免重复编写查询字段的同时,也能防止不小心查询了不必要的冗余字段,示例如下:
# 定义可复用的Person基础字段片段 fragment PersonBase on Person { id name avatar } # 查询时直接引用片段即可 query GetCurrentUser { me { follows { ...PersonBase } contacts { ...PersonBase } receivedMessages { id text author { ...PersonBase } } } }
以上方案落地后,可覆盖90%以上的冗余传输与重复处理问题,无需对现有业务逻辑做大规模改造。
内容的提问来源于stack exchange,提问作者Paso
相关产品推荐
相关产品推荐

