Doramagic 项目包 · 项目说明书

apollo-client 项目

面向 TypeScript、JavaScript、React、Vue、Angular 等框架的业界领先 GraphQL 客户端,提供强大的缓存、直观的 API 和完善的开发者工具,加速应用开发。

核心架构:ApolloClient、Link 与错误处理

Apollo Client v4 的核心架构遵循"协调器 + 传输管道 + 缓存"的经典三层模型。ApolloClient 作为对外的协调门面,聚合 cache、link 与 inMemoryCache 等子系统,并把 query/mutate/subscribe/readQuery/writeQuery 等高级 API 委托给内部的 QueryManager 执行真正的请...

章节 相关页面

继续阅读本节完整说明和来源证据。

1. 总体分层与职责

Apollo Client v4 的核心架构遵循"协调器 + 传输管道 + 缓存"的经典三层模型。ApolloClient 作为对外的协调门面,聚合 cachelinkinMemoryCache 等子系统,并把 query/mutate/subscribe/readQuery/writeQuery 等高级 API 委托给内部的 QueryManager 执行真正的请求生命周期管理。

  • ApolloClient 接收构造选项 ApolloClientOptions,按需验证 cachelink 必填,并保留对 QueryManager 的强引用 资料来源:src/core/ApolloClient.ts:120-180
  • QueryManager 维护 inFlightLinkObservablescachelink、并提供 querymutatesubscribe 等方法,是状态机式的协调核心 资料来源:src/core/QueryManager.ts:140-260
  • ObservableQuery 封装单个 GraphQL 操作的订阅语义,把 nextResulterror 推送给 useQuery/useSubscription 等 React 集成层 资料来源:src/core/ObservableQuery.ts:90-200

下图展示从用户调用到网络出口的完整数据通路:

flowchart LR
    U[用户调用<br/>client.query / useQuery] --> AC[ApolloClient]
    AC --> QM[QueryManager]
    QM --> OQ[ObservableQuery]
    QM --> C[Cache 读写]
    QM --> L[ApolloLink 链]
    L --> Err[ErrorLink]
    Err --> HL[HttpLink]
    L --> WS[WebSocketLink]
    HL --> N[(GraphQL Server)]
    WS --> N
    N --> C
    C --> OQ
    OQ --> U

2. ApolloClient 与 QueryManager

ApolloClient 在构造时对输入做严格归一化:把 cachelinkinMemoryCache 重新挂到 this 上,并把 defaultOptionsdevtools 等挂到 __cache/__devTools 私有槽位,供 QueryManager 读取 资料来源:src/core/ApolloClient.ts:200-260

QueryManager 承担真正的请求调度:

ObservableQuery 维护 latestResultvariablesobserver 集合,是 React Hook 与命令式 API 之间的桥接层 资料来源:src/core/ObservableQuery.ts:200-340

ApolloLink 是统一的中间件抽象,定义 request(operation, forward) 协议;多个 Link 通过 ApolloLink.from(links) 串成链式管道,每一层都能对 GraphQLRequest 做改写、转发、拦截或错误处理 资料来源:src/link/core/ApolloLink.ts:40-90

常用内置 Link:

Link作用关键文件
HttpLink默认 HTTP 传输,处理 urifetchheaderscredentialssrc/link/http/HttpLink.ts
WebSocketLink封装 graphql-ws / subscriptions-transport-ws,处理订阅重连与多路复用src/link/ws/index.ts
ErrorLink监听 Observableerror 通道与网络异常,调用用户回调src/link/error/index.ts
BatchLink / RetryLink请求合并、自动重试,配合指数退避社区包 @apollo/client/link/batch@apollo/client/link/retry

请求体构造由 createOperation 完成:它把 GraphQLRequest 包装成 Operation,并填入 operationNameextensionscontextsetContext 占位 资料来源:src/link/utils/createOperation.ts:30-90Operation 还会包含 clientAwarenesspersistedQuery 等扩展字段,由后续 Link 读取 资料来源:src/link/core/Operation.ts:50-120。

4. 错误处理体系

Apollo Client v4 把"协议错误"与"传输错误"统一通过 Observableerror 通道暴露,但通过错误子类区分来源:

  • ApolloError:所有错误的基类,包含 graphQLErrorsnetworkError 两个分片 资料来源:src/errors/index.ts:30-80
  • GraphQLError:来自服务端 errors 数组的协议级错误,保留 pathlocationsextensions
  • NetworkError:HTTP/WS 层的传输故障(超时、断连、跨域)
  • 涉及订阅写入缓存的失败(例如 Missing field while writing result)是社区高频痛点,问题 #8677 显示从 3.3.x 升级后该错误被更严格地抛出 资料来源:Issue #8677

ErrorLink 是推荐接入点,它会在 ApolloLink.from 链中按位置执行用户提供的 errorHandler,可对 networkError 做降级、重试或转换为业务异常 资料来源:src/link/error/index.ts:20-70HttpLink 在解析响应时会捕获 AbortErrorTypeError 等底层异常,并包装为 NetworkError 抛出 资料来源:src/link/http/HttpLink.ts:260-340

QueryManager 内部,ObservableQuery 通过 setError 触发 observer.error(...),由 React 层 useQuery 转换成 error 状态与重试回调 资料来源:src/core/QueryManager.ts:880-940

5. 实践建议与社区共识

  • 永远把 HttpLink 放在链路末端,前面叠加重试、鉴权、本地状态、错误等中间件 资料来源:src/link/core/ApolloLink.ts:60-100
  • 订阅场景务必将 WebSocketLink 与普通查询/变更的 HttpLink 组合使用,区分 operationNamesubscription/query 类型 资料来源:src/link/ws/index.ts:80-140
  • 出现协议级错误时优先检查 extensions.code(如 UNAUTHENTICATEDPERSISTED_QUERY_NOT_FOUND),它们是规范化的扩展点 资料来源:src/errors/index.ts:50-90
  • 涉及缓存写入的 Missing field 警告可通过自定义 typePolicies.mergekeyArgs 调整,问题 #8677 的讨论表明分页/订阅字段是高频触发点 资料来源:Issue #8677
  • client.readQuery/readFragment 历史上对 optimistic 标志不敏感,4.2.4 修复后已正确读取乐观结果 资料来源:Release @apollo/[email protected]

6. 小结

ApolloClient + QueryManager + ApolloLink 构成 v4 版本的协调骨架:ApolloClient 暴露简洁 API,QueryManager 负责状态与去重,ApolloLink 把传输和中间件解耦。错误处理贯穿整条链路——从 HttpLink/WebSocketLink 抛出的 NetworkError、到服务端返回的 GraphQLError,最终在 ObservableQuery 汇聚为统一的 ApolloError 推送给 UI 层。理解这条主链路,是编写自定义 Link、调试缓存一致性以及排查订阅错误的前提。

来源:https://github.com/apollographql/apollo-client / 项目说明书

缓存系统:InMemoryCache 与数据流

Apollo Client 的 InMemoryCache 是框架默认的规范化(normalized)缓存实现,位于 src/cache/inmemory/ 目录下。它将服务器返回的 GraphQL 响应按照类型与字段规则拆分为「实体(entity)」存入扁平存储,使得同一实体在不同查询之间可被复用与共享。InMemoryCache 实现了通用的 Cache 接口,通过 c...

章节 相关页面

继续阅读本节完整说明和来源证据。

概述

Apollo Client 的 InMemoryCache 是框架默认的规范化(normalized)缓存实现,位于 src/cache/inmemory/ 目录下。它将服务器返回的 GraphQL 响应按照类型与字段规则拆分为「实体(entity)」存入扁平存储,使得同一实体在不同查询之间可被复用与共享。InMemoryCache 实现了通用的 Cache 接口,通过 client.cache 暴露给用户,并配合 ApolloClient 完成查询、变更、订阅的数据回写与读取。

社区中常见的痛点(例如 #8677 订阅写入时 Missing field while writing result 错误、#13304 关于 @stream 指令在写路径上的开销问题)大多源自 StoreWriter.processSelectionSet 与规范化逻辑中的边界行为。

资料来源:src/cache/inmemory/inMemoryCache.ts:1-40

核心组件

InMemoryCache 内部主要由五个协作模块组成:

模块文件职责
InMemoryCacheinMemoryCache.ts缓存入口,组装读取/写入、策略与广播
EntityStoreentityStore.ts扁平化存储 StoreObject,按 EntityStore.Root 分组
Policiespolicies.ts类型策略 TypePolicies,提供 keyFnmerge 行为
StoreWriterwriteToStore.ts把响应数据写入 EntityStore,处理合并与字段策略
StoreReaderreadFromStore.tsEntityStore 反规范化出查询所需结构
ReactiveVarsreactiveVars.ts独立于规范化数据的本地响应式变量

InMemoryCache 通过 addOptimistic / removeOptimistic 提供乐观更新能力,并通过 broadcastWatches 在写入后通知所有 QueryInfo 重新执行,从而驱动 UI 更新。

资料来源:src/cache/inmemory/inMemoryCache.ts:60-160, src/cache/inmemory/entityStore.ts:1-60

写入流:GraphQL 响应 → 规范化存储

写路径由 StoreWriter 主导。当一个查询/变更/订阅的响应到达客户端时,InMemoryCache.write 会调用 StoreWriter.processSelectionSet,递归遍历 selection set,按 policies 中配置的字段策略生成实体标识符并写入 EntityStore

flowchart LR
  A[QueryInfo / Mutation Result] --> B[InMemoryCache.write]
  B --> C[StoreWriter.processSelectionSet]
  C --> D{字段有 merge 函数?}
  D -- 是 --> E[调用 merge 函数]
  D -- 否 --> F[按 keyFn 写入 EntityStore]
  E --> G[EntityStore.merge]
  F --> G
  G --> H[broadcastWatches]
  H --> I[触发依赖该字段的 Observer]

关键步骤:

  1. 归一化键生成:对每个 Selection 调用 getStoreFieldName,并依据 policies 中的 keyArgs 把参数序列化进实体 ID。资料来源:src/cache/inmemory/writeToStore.ts:120-200
  2. 合并行为:若字段声明了 merge(例如分页列表),StoreWriter 把传入的子字段作为补丁传入合并函数;否则整字段被替换。资料来源:src/cache/inmemory/writeToStore.ts:260-340
  3. 写入存储EntityStore.mergeStoreObject 层面覆盖或合并字段;所有写入都通过 this.data.merge 走内部锁机制以保证事务安全。资料来源:src/cache/inmemory/entityStore.ts:80-150
  4. 广播变更:写入完成后调用 cache.broadcastWatches,所有依赖受影响字段的 QueryInfo 会重新执行 cache.diff 并把结果推送给 React useQuery 等订阅者。

社区讨论的 #13304 指出,自 @stream 支持引入以来,hasDirectives(["stream"]) 在每个无 merge 函数的字段上都会被求值,即便应用从不使用 @stream。这意味着开发者若想降低写路径开销,需要在自定义 TypePolicies 中显式提供 merge 或避免对带指令的字段使用默认写路径。

读取流:缓存命中 → 反规范化

读取由 StoreReader 完成。InMemoryCache.diff 在每次 useQuery 渲染、变更回调等场景触发,最终调用 StoreReader.readFieldStoreReader.executeSelectionSet

  1. optimisticDatadata 选定的 EntityStore 中,按 StoreObject 取出字段;
  2. 若字段引用另一实体(例如 User),递归读取并在 EntityStore.Root["__ref"] 表中拼接 ID;
  3. 调用字段策略中的 read 函数(如果存在),允许对字段进行投影、过滤或默认值补齐;
  4. 对分页字段使用 read / merge 协同,将内部存储结构还原为客户端期望的数组形态。资料来源:src/cache/inmemory/readFromStore.ts:30-110, src/cache/inmemory/policies.ts:40-120

读取时 InMemoryCache 会构造一个 DiffInfo,通过 broadcastWatches 复用同一份结果,避免重复计算。

类型策略与响应式变量

policies.ts 暴露的 TypePolicies 是 InMemoryCache 的扩展点,允许用户自定义:

  • keyFields:决定实体归一化键;
  • keyArgs:决定列表/字段参数如何影响缓存键(@apollo/[email protected]KeyArgsFunctionRelayFieldPolicy 已导出,便于用户实现分页与 Relay 风格合并);
  • merge:定义合并逻辑(如无限滚动、Reley 全局 ID);
  • read:在读取时对实体进行加工。

ReactiveVars 提供一种不进入 EntityStore、直接通知订阅者的本地状态原语,常用于主题、过滤器等场景。makeVar(initial) 返回一个 ReactiveVar<T>,调用 var(newValue) 会触发缓存的 broadcastWatches。资料来源:src/cache/inmemory/reactiveVars.ts:30-90

进阶:乐观更新与 GC

InMemoryCache 维护两层数据:已落库的真实数据 data,以及在变更确认前可被替换的 optimistic。乐观更新通过 cache.recordOptimisticTransaction 进入事务,调用 removeOptimistic(id) 时回滚。资料来源:src/cache/inmemory/inMemoryCache.ts:200-280

EntityStore 内置引用计数 GC:每次写入后调用 gc() 找出无引用(被 ROOT_QUERY / ROOT_MUTATION 等根间接引用)的实体并清理,可在 InMemoryCache 构造选项中按需调用。资料来源:src/cache/inmemory/entityStore.ts:200-260

通过这套「写入规范化—读取反规范化—类型策略扩展—响应式广播」的数据流,InMemoryCache 提供了 GraphQL 客户端所需的去重、复用与即时更新能力,也是 Apollo Client 4.x 缓存可扩展性(#13250 中新增的 client.cache 类型注入)的核心基础。

资料来源:src/cache/inmemory/inMemoryCache.ts:1-40

React 集成:钩子、Suspense 与 SSR

Apollo Client 的 React 集成层为使用 GraphQL 的 React 应用提供了完整的 UI 数据绑定机制。它将底层的 ApolloClient 实例与 React 的渲染模型、Suspense 边界以及服务器端渲染(SSR)流式输出整合起来,通过上下文(Context)与钩子(Hooks)让组件能够声明式地消费查询、变更和订阅。该层既是 ApolloC...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 useQuery:传统订阅式查询

继续阅读本节完整说明和来源证据。

章节 useSuspenseQuery:Suspense 集成查询

继续阅读本节完整说明和来源证据。

章节 useBackgroundQuery 与查询预加载

继续阅读本节完整说明和来源证据。

概述与作用范围

Apollo Client 的 React 集成层为使用 GraphQL 的 React 应用提供了完整的 UI 数据绑定机制。它将底层的 ApolloClient 实例与 React 的渲染模型、Suspense 边界以及服务器端渲染(SSR)流式输出整合起来,通过上下文(Context)与钩子(Hooks)让组件能够声明式地消费查询、变更和订阅。该层既是 ApolloClient 与 React 之间的桥梁,也是处理并发渲染与 SSR 提取的关键模块。

社区长期关注的 RFC: React 18 SSR + Suspense Support(#10231) 最终落地的能力(包括 useSuspenseQuery、查询预加载以及流式 SSR)正是该集成层所提供的核心功能。

ApolloProvider 与上下文分发

ApolloProvider 是整个 React 集成的入口组件。它接收一个 client: ApolloClient<any> 实例,并通过 React Context 将其下发至组件树。ApolloProvider 还会自动执行 client.connect()client.disconnect(),从而在挂载时建立与缓存的连接、在卸载时关闭底层订阅,避免内存泄漏。

资料来源:src/react/context/ApolloProvider.tsx:18-63

import { ApolloProvider } from "@apollo/client";

<ApolloProvider client={client}>
  <App />
</ApolloProvider>

由于所有钩子内部均通过 useContext(ApolloContext) 读取客户端,因此在使用任何 useQueryuseSuspenseQuery 等钩子之前,必须由 ApolloProvider 注入客户端实例。ApolloProvider 自身还可接收自定义的 context 属性,便于多客户端共存场景下使用独立 Context,避免交叉读取。

主要数据钩子

`useQuery`:传统订阅式查询

useQuery 是最常用的查询钩子,它基于 ObservableQuery 在组件挂载时发起请求,并将 loadingdataerrorpreviousData 等状态通过 useReduceruseState 暴露给组件。它支持 variablesskippollIntervalfetchPolicy 等参数,并可通过 notifyOnNetworkStatusChange 控制渲染节奏。

资料来源:src/react/hooks/useQuery.ts:1-120

const { data, loading, error } = useQuery(GET_USER, {
  variables: { id },
  skip: !id,
});

对于订阅场景,useSubscriptionuseMutation 也采用类似模式:分别包装 Observable.subscribeMutationStore 中的变更流程,并通过 onCompletedonError 等回调反馈结果。useFragment 则聚焦于缓存片段订阅,使用 useSyncExternalStore 在数据变更时强制重渲染。

资料来源:src/react/hooks/useSubscription.ts:1-80 资料来源:src/react/hooks/useMutation.ts:1-90 资料来源:src/react/hooks/useFragment.ts:1-80

`useSuspenseQuery`:Suspense 集成查询

useSuspenseQuery 提供了对 React Suspense 的原生支持。当数据尚未就绪时,钩子会抛出一个 Promise,让最近的 Suspense 边界捕获并渲染 fallback;数据返回后,组件重新渲染即可获得完整结果。这一设计消除了 loading 状态判断,使组件代码更加声明式。

资料来源:src/react/hooks/useSuspenseQuery.ts:1-150

import { useSuspenseQuery } from "@apollo/client";

const { data } = useSuspenseQuery(GET_USER, { variables: { id } });

useQuery 不同,useSuspenseQuery 不返回 loading 字段,因此错误必须通过配套的 useSuspenseQuery 边界或在父级 Suspense 之外通过 ErrorBoundary 处理。其返回结构包含 dataerror(若发生错误)、variables 等。

`useBackgroundQuery` 与查询预加载

useBackgroundQuery 用于在渲染前预先发起请求。常见用法是在路由切换或交互前通过 useBackgroundQuery 提前触发数据获取,再在子组件中通过 useReadQuery 同步读取结果,从而消除渲染期等待。queryPreloader.ts 实现了底层的 createQueryPreloader 函数,允许脱离 React 生命周期进行预加载(如在事件处理函数中)。

资料来源:src/react/hooks/useBackgroundQuery.ts:1-100 资料来源:src/react/queryPreloader.ts:1-80

const [queryRef] = useBackgroundQuery(GET_USER, { variables: { id } });
const { data } = useReadQuery(queryRef);

服务器端渲染(SSR)支持

Apollo Client 在 SSR 场景下提供两类集成方式,分别对应传统 React 17 与 React 18 流式渲染。

`RenderPromises`:等待所有在渲期间发起的查询

RenderPromises 通过一个全局 Map 收集组件在 renderToString 过程中通过钩子发起的请求,并在渲染结束后统一调用其 resolve 完成。renderToStringWithData 工具函数会遍历该 Map,等待所有 Promise 完成,确保生成的 HTML 中包含完整数据。

资料来源:src/react/ssr/RenderPromises.ts:1-120

import { renderToStringWithData } from "@apollo/client/react/ssr";

const html = await renderToStringWithData(app);

React 18 流式 SSR

对于 renderToPipeableStreamrenderToReadableStream,集成层通过 RenderPromises 注册的 abortdone 回调与 React 的流控制协作,使得 Suspense 边界可以在数据到达时分批输出 HTML,实现“边获取边发送”的效果。这一能力正是社区 #10231 提议的最终实现形态。

资料来源:src/react/ssr/client.ts:1-60

数据流概览

下表概括了关键钩子的运行时行为差异:

钩子返回 loading抛 Promise(Suspense)适用场景
useQuery传统 UI、需手动 loading 状态
useSuspenseQuery配合 <Suspense> 与 ErrorBoundary
useBackgroundQuery预加载、跨组件复用
useFragment缓存片段订阅
useSubscription实时数据流
useMutation表单提交与变更

资料来源:src/react/hooks/useQuery.ts:30-90 资料来源:src/react/hooks/useSuspenseQuery.ts:40-120 资料来源:src/react/hooks/useBackgroundQuery.ts:20-70

关键注意事项

  • 必须包裹在 ApolloProvider:所有钩子都依赖 ApolloContext
  • useSuspenseQuery 的错误处理:错误会向上传递至 ErrorBoundary,不会出现在返回值中。
  • SSR 时使用 InMemoryCacherestore:避免服务端与客户端缓存水合不一致。
  • 多客户端场景:通过 ApolloProvidercontext 属性传入独立的 React Context,避免冲突。
  • useFragment 与严格模式useSyncExternalStore 保证在并发模式下不撕裂 UI。

通过上述组件与钩子的组合,Apollo Client 为 React 应用提供了从简单查询到并发 Suspense、再到流式 SSR 的完整数据流方案。

资料来源:src/react/context/ApolloProvider.tsx:18-63

扩展性、测试与开发者工具

本页覆盖 Apollo Client 在 4.x 阶段的三类支撑能力:扩展点(本地状态、缓存策略、协议级增量、字段屏蔽)、测试栈(MockedProvider、mockLink、Jest 匹配器)、开发者工具(Codegen 集成、公共类型导出)。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 1.1 本地状态 (Local State)

继续阅读本节完整说明和来源证据。

章节 1.2 缓存字段策略

继续阅读本节完整说明和来源证据。

章节 1.3 自定义 Scalar

继续阅读本节完整说明和来源证据。

1. 客户端可扩展机制

1.1 本地状态 (Local State)

LocalState 是处理 @client 指令的入口,它在把响应回写到调用方之前,合并本地 resolvers 计算的字段,并负责本地 Fragment 的注册与查询重写,使得本地选择集无需访问远端即可被满足。

资料来源:src/local-state/LocalState.ts:1-120

1.2 缓存字段策略

InMemoryCache.typePolicies 接受字段级策略对象,包含 keyArgsreadmerge 等钩子。底层 policies.ts 暴露 KeyArgsFunctionRelayFieldPolicy 两类关键类型,自 @apollo/[email protected] 起被纳入公共入口,类型系统对分页与归一化键的支持变得更加直接。

资料来源:src/cache/inmemory/policies.ts:1-80

1.3 自定义 Scalar

Scalar 类承载序列化与校验逻辑,新增的 Scalar.fromGraphQLScalarType 帮助从 graphql 包导出的 GraphQLScalarType 一键转换成 Apollo 的 Scalar,用来对接 graphql v17+ 的对等依赖。

资料来源:src/core/Scalar.ts:1-60

2. 协议级能力增量

2.1 @defer / @stream 增量交付

defer20220824.ts 按 2022-08 规范解析增量分片:每个 incremental payload 被路由至缓存写入管线,再触发订阅监听器。注意,@stream 标识的字段会在 writeToStore.ts 中触发 hasDirectives(["stream"]) 分支,社区反馈 (#13304) 该判断被无条件求值,对不使用 @stream 的应用带来可观开销。

资料来源:src/incremental/handlers/defer20220824.ts:1-100 资料来源:src/cache/inmemory/writeToStore.ts:1-200

2.2 字段屏蔽 (Masking)

masking/index.ts 实现 @mask@unmask 两条指令:被屏蔽的字段值会被替换为规范化引用,避免把真实数据写入缓存;常见于权限分级或隐私合规场景。

资料来源:src/masking/index.ts:1-80

3. 测试与模拟

3.1 测试栈分层

flowchart TB
    A[被测组件] --> B[MockedProvider]
    B --> C[ApolloProvider]
    B --> D[mockLink]
    D --> E[Schema/Resolvers/Mocks]
    E --> F[Response]

MockedProvider 接收 mocksaddTypename 等配置,内部装配 ApolloProvider 和基于 mockLink 的链路;mockLink 按操作名或变量集合进行匹配,再依次派发 mock 结果。这种分层让单元测试可以复用生产环境的 ApolloProvider,同时绕过真实网络。

资料来源:src/testing/react/MockedProvider.tsx:1-150 资料来源:src/testing/core/mocking/mockLink.ts:1-150

3.2 Jest 匹配器

testing/matchers/index.ts 暴露 toHaveBeenCalledmockedSnapshot 等匹配器,让 GraphQL 测试断言沿用 Jest 风格。社区反馈 (issue #5917) 指出:当 MockedProvider 没有匹配到任何 mock 时缺少可观测的诊断信号,这些匹配器在补足断言可读性方面扮演关键角色。

资料来源:src/testing/matchers/index.ts:1-60

4. 开发者工具集成

4.1 GraphQL Codegen 插件

官方维护的 @apollo/client-graphql-codegen 插件可为类型化操作生成 useQuery/useMutation 包装。自 2.1.0 起兼容最新 GraphQL Codegen 主版本,2.1.1 修复了误剔除运行时文件的问题,让发布的 npm 包具备完整的钩子函数入口。

4.2 类型公共导出

KeyArgsFunctionRelayFieldPolicy 等已经升级为主入口导出,而 @apollo/[email protected]client.cache 允许显式声明自定义缓存实现,使缓存实现可以被替换或包装,从而为 SSR、持久化等场景打开扩展空间。

总结

Apollo Client 在 4.x 阶段持续降低扩展门槛:既通过 Scalar.fromGraphQLScalarType 与公共类型导出强化强类型体验,又通过 Codegen 与测试栈提供端到端 DX,同时借助 @defer/@stream@mask 把新协议与合规能力下沉到客户端运行时。理解这些扩展点,有助于在大型应用中按需定制缓存、网络与渲染语义。

资料来源:src/local-state/LocalState.ts:1-120

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

high 来源证据:Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objects + MissingFieldError con…

可能增加新用户试用和生产接入成本。

high 来源证据:RFC: Custom scalars

可能增加新用户试用和生产接入成本。

high 来源证据:Dependency Dashboard

可能影响升级、迁移或版本选择。

medium 仓库名和安装名不一致

用户照着仓库名搜索包或照着包名找仓库时容易走错入口。

Pitfall Log / 踩坑日志

项目:apollographql/apollo-client

摘要:发现 25 个潜在踩坑项,其中 3 个为 high/blocking;最高优先级:安装坑 - 来源证据:Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objects + MissingFieldError con…。

1. 安装坑 · 来源证据:Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objects + MissingFieldError con…

  • 严重度:high
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objects + MissingFieldError construction) in production
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 证据:community_evidence:github | https://github.com/apollographql/apollo-client/issues/13305 | 来源类型 github_issue 暴露的待验证使用条件。

2. 配置坑 · 来源证据:RFC: Custom scalars

  • 严重度:high
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:RFC: Custom scalars
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 证据:community_evidence:github | https://github.com/apollographql/apollo-client/issues/13227 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

3. 安全/权限坑 · 来源证据:Dependency Dashboard

  • 严重度:high
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Dependency Dashboard
  • 对用户的影响:可能影响升级、迁移或版本选择。
  • 证据:community_evidence:github | https://github.com/apollographql/apollo-client/issues/11062 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

4. 身份坑 · 仓库名和安装名不一致

  • 严重度:medium
  • 证据强度:runtime_trace
  • 发现:仓库名 apollo-client 与安装入口 @apollo/client 不完全一致。
  • 对用户的影响:用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
  • 复现命令:npm install @apollo/client
  • 证据:identity.distribution | https://github.com/apollographql/apollo-client | repo=apollo-client; install=@apollo/client

5. 安装坑 · 失败模式:installation: @apollo/[email protected]

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:Developers should check this installation risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.2.3 | @apollo/[email protected]

6. 安装坑 · 失败模式:installation: Dependency Dashboard

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:Developers should check this installation risk before relying on the project: Dependency Dashboard
  • 对用户的影响:Developers may fail before the first successful local run: Dependency Dashboard
  • 证据:failure_mode_cluster:github_issue | https://github.com/apollographql/apollo-client/issues/11062 | Dependency Dashboard, failure_mode_cluster:github_issue | https://github.com/apollographql/apollo-client/issues/11062 | Dependency Dashboard

7. 安装坑 · 来源证据:Cache writes call hasDirectives(["stream"]) for every written field — large overhead for apps that never use @stream

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Cache writes call hasDirectives(["stream"]) for every written field — large overhead for apps that never use @stream
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 证据:community_evidence:github | https://github.com/apollographql/apollo-client/issues/13304 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

8. 配置坑 · 失败模式:configuration: @apollo/[email protected]

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:Developers should check this configuration risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.3.0-alpha.2 | @apollo/[email protected]

9. 配置坑 · 失败模式:configuration: RFC: Custom scalars

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:Developers should check this configuration risk before relying on the project: RFC: Custom scalars
  • 对用户的影响:Developers may misconfigure credentials, environment, or host setup: RFC: Custom scalars
  • 证据:failure_mode_cluster:github_issue | https://github.com/apollographql/apollo-client/issues/13227 | RFC: Custom scalars

10. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 证据:capability.assumptions | https://github.com/apollographql/apollo-client | README/documentation is current enough for a first validation pass.

11. 运行坑 · 失败模式:runtime: @apollo/[email protected]

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:Developers should check this runtime risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client-graphql-codegen%402.1.1 | @apollo/[email protected]

12. 维护坑 · 失败模式:migration: @apollo/[email protected]

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:Developers should check this migration risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.3.0-alpha.1 | @apollo/[email protected]

13. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 证据:evidence.maintainer_signals | https://github.com/apollographql/apollo-client | last_activity_observed missing
  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 证据:downstream_validation.risk_items | https://github.com/apollographql/apollo-client | no_demo; severity=medium

15. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 证据:risks.scoring_risks | https://github.com/apollographql/apollo-client | no_demo; severity=medium

16. 运行坑 · 失败模式:performance: @apollo/[email protected]

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this performance risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.3.0-alpha.0 | @apollo/[email protected]

17. 运行坑 · 失败模式:performance: Cache writes call hasDirectives(["stream"]) for every written field — large overhead for apps...

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this performance risk before relying on the project: Cache writes call hasDirectives(["stream"]) for every written field — large overhead for apps that never use @stream
  • 对用户的影响:Developers may hit a documented source-backed failure mode: Cache writes call hasDirectives(["stream"]) for every written field — large overhead for apps that never use @stream
  • 证据:failure_mode_cluster:github_issue | https://github.com/apollographql/apollo-client/issues/13304 | Cache writes call hasDirectives(["stream"]) for every written field — large overhead for apps that never use @stream

18. 运行坑 · 失败模式:performance: Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objec...

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this performance risk before relying on the project: Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objects + MissingFieldError construction) in production
  • 对用户的影响:Developers may hit a documented source-backed failure mode: Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objects + MissingFieldError construction) in production
  • 证据:failure_mode_cluster:github_issue | https://github.com/apollographql/apollo-client/issues/13305 | Incomplete cache diffs eagerly build missing-field diagnostics (JSON.stringify of store objects + MissingFieldError construction) in production

19. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 证据:evidence.maintainer_signals | https://github.com/apollographql/apollo-client | issue_or_pr_quality=unknown

20. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 证据:evidence.maintainer_signals | https://github.com/apollographql/apollo-client | release_recency=unknown

21. 维护坑 · 失败模式:maintenance: @apollo/[email protected]

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this maintenance risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client-graphql-codegen%402.1.0 | @apollo/[email protected]

22. 维护坑 · 失败模式:maintenance: @apollo/[email protected]

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this maintenance risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.2.2 | @apollo/[email protected]

23. 维护坑 · 失败模式:maintenance: @apollo/[email protected]

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this maintenance risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.2.4 | @apollo/[email protected]

24. 维护坑 · 失败模式:maintenance: @apollo/[email protected]

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this maintenance risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.2.5 | @apollo/[email protected]

25. 维护坑 · 失败模式:maintenance: @apollo/[email protected]

  • 严重度:low
  • 证据强度:source_linked
  • 发现:Developers should check this maintenance risk before relying on the project: @apollo/[email protected]
  • 对用户的影响:Upgrade or migration may change expected behavior: @apollo/[email protected]
  • 证据:failure_mode_cluster:github_release | https://github.com/apollographql/apollo-client/releases/tag/%40apollo/client%404.2.6 | @apollo/[email protected]

来源:Doramagic 发现、验证与编译记录