跳至主内容
版本:11.x

链接概述

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

链接(Links)允许您自定义 tRPC 客户端与服务器之间的数据流。每个链接应专注于单一功能:可以是对 tRPC 操作(查询、变更或订阅)的独立修改,也可以是基于操作的副作用(如日志记录)。

您可以将多个链接组合成数组,通过 tRPC 客户端配置中的 links 属性构建链接链。这意味着 tRPC 客户端会在发起请求时按 links 数组顺序执行链接,并在处理响应时以相反顺序再次执行。以下是链接链的示意图:

tRPC Link DiagramtRPC Link Diagram. Based on Apollo's.
utils/trpc.ts
ts
import { createTRPCClient, httpBatchLink, loggerLink } from '@trpc/client';
import type { AppRouter } from './server';
 
export const trpc = createTRPCClient<AppRouter>({
links: [
loggerLink(),
httpBatchLink({
url: 'http://localhost:3000',
}),
],
});
utils/trpc.ts
ts
import { createTRPCClient, httpBatchLink, loggerLink } from '@trpc/client';
import type { AppRouter } from './server';
 
export const trpc = createTRPCClient<AppRouter>({
links: [
loggerLink(),
httpBatchLink({
url: 'http://localhost:3000',
}),
],
});

创建自定义链接

链接是符合 TRPCLink 类型的函数,由三部分构成:

  1. 链接返回一个无参数的函数,这是链接的初始化阶段(setup phase)——该阶段在每个应用中仅发生一次,适用于存储缓存或其他状态。

  2. 上一步的函数返回另一个函数,该函数接收包含两个属性的对象:op 表示客户端正在执行的 Operationnext 用于调用链中的下一个链接。

  3. 上一步的函数最终返回 @trpc/server 提供的 observable 函数。observable 接收包含 observer 的函数,该观察者帮助链接通知链中上游链接如何处理操作结果。在此函数中,可直接返回 next(op) 保持原样,也可订阅 next 使链接能处理操作结果。

示例

utils/customLink.ts
tsx
import { TRPCLink } from '@trpc/client';
import { observable } from '@trpc/server/observable';
import type { AppRouter } from './server';
 
export const customLink: TRPCLink<AppRouter> = () => {
// here we just got initialized in the app - this happens once per app
// useful for storing cache for instance
return ({ next, op }) => {
// this is when passing the result to the next link
 
// each link needs to return an observable which propagates results
return observable((observer) => {
console.log('performing operation:', op);
const unsubscribe = next(op).subscribe({
next(value) {
console.log('we received value', value);
observer.next(value);
},
error(err) {
console.log('we received error', err);
observer.error(err);
},
complete() {
observer.complete();
},
});
 
return unsubscribe;
});
};
};
utils/customLink.ts
tsx
import { TRPCLink } from '@trpc/client';
import { observable } from '@trpc/server/observable';
import type { AppRouter } from './server';
 
export const customLink: TRPCLink<AppRouter> = () => {
// here we just got initialized in the app - this happens once per app
// useful for storing cache for instance
return ({ next, op }) => {
// this is when passing the result to the next link
 
// each link needs to return an observable which propagates results
return observable((observer) => {
console.log('performing operation:', op);
const unsubscribe = next(op).subscribe({
next(value) {
console.log('we received value', value);
observer.next(value);
},
error(err) {
console.log('we received error', err);
observer.error(err);
},
complete() {
observer.complete();
},
});
 
return unsubscribe;
});
};
};

参考

如需更实际的参考实现,可查看 tRPC 在 GitHub 提供的内置链接源码。

终止链接

终止链接是链接链的最后一环。它不调用 next 函数,而是负责将组合好的 tRPC 操作发送至 tRPC 服务器,并返回 OperationResultEnvelope

添加到 tRPC 客户端配置的 links 数组必须包含至少一个终止链接。若 links 的末尾没有终止链接,则 tRPC 操作将无法发送至服务器。

httpBatchLink 是 tRPC 推荐的终止链接。

根据需求,httpLinkhttpBatchStreamLinkhttpSubscriptionLinkwsLinklocalLink 也是终止链接的其他实现方案。

管理上下文

操作在链接链中传递时会维护一个上下文,每个链接均可读取和修改此上下文,使链接能沿链传递元数据供其他链接执行逻辑使用。

通过访问 op.context 可获取当前上下文对象并进行修改。

您可通过向 queryuseQuery 钩子(或 mutationsubscription 等)提供 context 参数,为特定操作设置上下文初始值。

有关具体用例示例,请参阅为特定请求禁用批处理功能