链接概述
链接使您能够自定义 tRPC 客户端和服务器之间数据流。链接应该只做一件事,这可以是对 tRPC 操作(查询、变异或订阅)的独立修改,也可以是基于操作的副作用(例如日志记录)。
您可以将链接组合成一个数组,并通过 links
属性提供给 tRPC 客户端配置,该属性表示链接链。这意味着 tRPC 客户端将在执行请求时按添加到 links
数组的顺序执行链接,并在处理响应时反向执行它们。以下是链接链的视觉表示
以下示例假设您使用 Next.js,但如果您使用原生 tRPC 客户端,则可以添加与以下相同的示例
utils/trpc.tstsx
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.tstsx
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
类型的函数。每个链接都由三个部分组成
- 链接返回一个函数,该函数具有一个带有
TRPCClientRuntime
类型的参数。此参数由 tRPC 传递,并在创建 终止链接 时使用。如果您没有创建终止链接,则可以只创建一个没有参数的函数。在这种情况下,链接应添加到links
数组中而不调用(links: [..., myLink, httpBatchLink(...)]
)。 - 步骤 1 中的函数返回另一个函数,该函数接收一个具有两个属性的对象:
op
是客户端正在执行的Operation
,next
是我们用来调用链中下一个链接的函数。 - 步骤 2 中的函数返回一个最终函数,该函数返回
@trpc/server
提供的observable
函数。observable
接受一个函数,该函数接收一个observer
,它帮助我们的链接通知链中下一个链接如何处理操作结果。在这个函数中,我们可以只返回next(op)
并保持原样,或者我们可以订阅next
,这使我们的链接能够处理操作结果。
示例
utils/customLink.tstsx
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 instancereturn ({ next, op }) => {// this is when passing the result to the next link// each link needs to return an observable which propagates resultsreturn 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.tstsx
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 instancereturn ({ next, op }) => {// this is when passing the result to the next link// each link needs to return an observable which propagates resultsreturn 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 操作将不会发送到 tRPC 服务器。
httpBatchLink
是 tRPC 推荐的终止链接。
管理上下文
当操作沿着您的链接链移动时,它会维护一个上下文,每个链接都可以读取和修改该上下文。这允许链接沿着链传递元数据,其他链接在执行逻辑中使用这些元数据。
通过访问 op.context
获取当前上下文对象并修改它。
您可以通过向 query
或 useQuery
钩子(或 mutation
、subscription
等)提供上下文参数来设置特定操作的上下文对象的初始值。
有关示例用例,请参阅 为某些请求禁用批处理。