跳至主内容
版本:10.x

链接概述

非官方测试版翻译

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

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

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

tRPC Link DiagramtRPC Link Diagram. Based on Apollo's.
备注

以下示例假设您使用 Next.js,但若使用原生 tRPC 客户端,同样可应用相同配置

utils/trpc.ts
tsx
import { httpBatchLink, loggerLink } from '@trpc/client';
import { createTRPCNext } from '@trpc/next';
export default createTRPCNext<AppRouter>({
config() {
const url = `http://localhost:3000`;
return {
links: [
loggerLink(),
httpBatchLink({
url,
}),
],
};
},
});
utils/trpc.ts
tsx
import { httpBatchLink, loggerLink } from '@trpc/client';
import { createTRPCNext } from '@trpc/next';
export default createTRPCNext<AppRouter>({
config() {
const url = `http://localhost:3000`;
return {
links: [
loggerLink(),
httpBatchLink({
url,
}),
],
};
},
});

创建自定义链接

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

  1. 链接返回一个带 TRPCClientRuntime 类型参数的函数。该参数由 tRPC 传入,用于创建终止链接。若非创建终止链接,可直接返回无参函数。此时链接应直接添加到 links 数组而不调用(如 links: [..., myLink, httpBatchLink(...)])。

  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/routers/_app';
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/routers/_app';
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 推荐的终止链接。

httpLinkwsLink 是其他终止链接的示例。

管理上下文

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

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

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

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