メインコンテンツへスキップ
バージョン: 11.x

Links 概要

非公式ベータ版翻訳

このページは 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型に従う関数です。各リンクは3つの部分で構成されます:

  1. リンクはTRPCClientRuntime型のパラメータを持つ関数を返します。この引数はtRPCによって渡され、終端リンク作成時に使用されます。終端リンクを作成しない場合は、パラメータのない関数を作成し、links配列に呼び出しなしで追加します(links: [..., myLink, httpBatchLink(...)])。

  2. ステップ1の関数は、クライアントが実行中のOperationであるopと、チェーン内の次のリンクを呼び出すnext関数の2つのプロパティを持つオブジェクトを受け取る別の関数を返します。

  3. ステップ2の関数は、@trpc/serverが提供するobservable関数を返す最終関数を返します。observableobserverを受け取る関数を引数に取り、リンクが操作結果を処理する方法を上位チェーンに通知します。この関数内では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配列には少なくとも1つのリンクが必要で、それは終端リンクである必要があります。もしlinksの末尾に終端リンクがない場合、tRPC操作はサーバーに送信されません。

httpBatchLinkはtRPCが推奨する終端リンクです。

その他の終端リンクの例として、httpLinkwsLinklocalLinkがあります。

コンテキスト管理

操作がリンクチェーンを移動する際、各リンクが読み取り・変更可能なコンテキストを維持します。これによりリンク間でメタデータを伝搬させ、他のリンクの実行ロジックで使用できます。

現在のコンテキストオブジェクトの取得と変更はop.contextで行います。

特定の操作に対するコンテキストオブジェクトの初期値は、queryuseQueryフック(またはmutationsubscriptionなど)にcontextパラメータを渡すことで設定できます。

使用例については、特定のリクエストでのバッチ処理の無効化を参照してください。