GraphQL 客户端开发需要掌握哪些核心知识?
GraphQL 客户端开发需要掌握哪些核心知识?
GraphQL 客户端的核心职责是把查询、缓存、状态管理三件事做好。Apollo Client 是目前最主流的选择,面试中围绕它的问题也最多。
Apollo Client 的缓存机制是怎样的?
Apollo Client 使用规范化缓存(Normalized Cache),把每个对象按 __typename:id 拆开存储,而不是按查询维度缓存整棵树。这意味着同一用户在不同查询中返回时,缓存只存一份,修改一处全局生效。
InMemoryCache 的 typePolicies 可以自定义合并策略。分页场景下用 merge 函数拼接新旧数据,用 keyArgs 声明哪些参数影响缓存键。
追问:cache-and-network 和 network-only 有什么区别?
cache-and-network 先返回缓存数据再发请求更新,适合需要即时反馈的列表页;network-only 跳过缓存直接请求,适合对数据新鲜度要求高的场景。
useQuery 的 fetchPolicy 怎么选?
常用策略按优先级排列:
- cache-first(默认):有缓存就用,没有才请求。适合读多写少的详情页
- cache-and-network:缓存和请求并行,先展示旧数据再更新。适合列表页
- network-only:每次都请求,适合订单状态等实时数据
- cache-only:只用缓存,离线场景或纯本地数据时使用
选错策略是缓存不更新的头号原因。比如详情页用了 cache-first,编辑后返回列表,数据没变——因为缓存没失效。
如何处理 Mutation 后的缓存更新?
三种方式,按推荐程度排序:
- cache.modify + writeFragment:手动更新缓存中受影响的字段,精确且高效
- refetchQueries:Mutation 成功后重新查询指定 Query,简单但多一次网络请求
- 乐观更新(Optimistic Response):先假设成功更新 UI,服务端返回后再修正,体验最好但实现复杂
实际项目中推荐方式 1 为主,关键操作加乐观更新。避免滥用 refetchQueries,它会让请求量翻倍。
分页加载怎么实现?
偏移分页用 fetchMore 传入新的 offset,在 updateQuery 中拼接结果。游标分页用 after 游标,配合 pageInfo.hasNextPage 判断是否还有数据。
游标分页更适合实时性强的场景(聊天记录、动态流),因为偏移分页在数据插入后会导致重复或遗漏。但游标分页不支持跳页,只能顺序加载。
全局错误处理怎么配置?
用 onError Link 统一拦截。graphQLErrors 是业务逻辑错误(校验失败、权限不足),networkError 是网络层错误(断网、超时)。
认证过期是常见场景:在 onError 中检测 401 错误码,静默刷新 Token 后用 forward(operation) 重发请求,用户无感知。
Subscription 在生产环境要注意什么?
WebSocket 连接不稳定是最大问题。必须实现自动重连:Apollo Client 的 split Link 按 Operation 类型分流,Query/Mutation 走 HTTP,Subscription 走 WebSocket。WebSocket 断开后用指数退避重连,避免服务器压力过大。
还要注意连接鉴权——WebSocket 建连时通过 connectionParams 传递 Token,服务端在 onConnect 中验证。
Apollo Link 链式调用原理是什么?
Apollo Link 采用中间件模式,每个 Link 处理请求后传给下一个。常用链路:authLink → errorLink → httpLink。setContext 注入请求头,onError 捕获错误,HttpLink 发出请求。顺序很重要——errorLink 放在 httpLink 前面才能拦截到网络错误。
掌握缓存策略选择、Mutation 缓存更新、分页实现、错误处理这四块,基本覆盖了 GraphQL 客户端面试的核心考察点。理解规范缓存的存储模型是串联所有知识点的基础。