HTTPバッチストリームリンク
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
httpBatchStreamLinkは終端リンクであり、個々のtRPC操作の配列を単一のHTTPリクエストにバッチ処理し(httpBatchLinkと同等)、単一のtRPCプロシージャに送信します。ただし、バッチ内のすべてのレスポンスの準備が整うのを待たず、データが利用可能になるとすぐにレスポンスをストリーミングします。
オプション
オプションはhttpBatchLink optionsと同一です。
使用方法
使用方法とオプションはすべて
httpBatchLinkと同一です。
プロシージャ内からレスポンスヘッダー(Cookieを含む)を変更/設定する機能が必要な場合は、代わりにhttpBatchLinkを使用してください!これは、httpBatchStreamLinkがストリーム開始後のヘッダー設定をサポートしないためです。詳細はこちら。
httpBatchStreamLinkをインポートしてlinks配列に追加する例:
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
その後、すべてのプロシージャをPromise.allで設定することでバッチ処理を活用できます。以下のコードは単一のHTTPリクエストを生成し、サーバー側では単一のデータベースクエリを実行します:
tsconst somePosts = await Promise.all([trpc.post.byId.query(1),trpc.post.byId.query(2),trpc.post.byId.query(3),]);
tsconst somePosts = await Promise.all([trpc.post.byId.query(1),trpc.post.byId.query(2),trpc.post.byId.query(3),]);
ストリーミングモード
リクエストをバッチ処理する際、通常のhttpBatchLinkはすべてのリクエストが完了するまでレスポンスを送信しません。レスポンスの準備が整い次第すぐに送信したい場合は、代わりにhttpBatchStreamLinkを使用できます。これは長時間実行されるリクエストに有効です。
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
通常のhttpBatchLinkと比較して、httpBatchStreamLinkは以下の挙動を示します:
-
リクエストに
trpc-accept: application/jsonlヘッダーを付与する -
レスポンスを
transfer-encoding: chunkedおよびcontent-type: application/jsonlで送信する -
responseMetaに渡される引数オブジェクトからdataキーを削除する(ストリーミングレスポンスではヘッダーがデータ利用前に送信されるため)
非同期ジェネレータと遅延プロミス
tRPC.ioのホームページで実際に試すことができます:https://trpc.io/?try=minimal#try-it-out
ts// @filename: server.tsimport {publicProcedure ,router } from './trpc';constappRouter =router ({examples : {iterable :publicProcedure .query (async function* () {for (leti = 0;i < 3;i ++) {await newPromise ((resolve ) =>setTimeout (resolve , 500));yieldi ;}}),},});export typeAppRouter = typeofappRouter ;// @filename: client.tsimport {createTRPCClient ,httpBatchStreamLink } from '@trpc/client';import type {AppRouter } from './server';consttrpc =createTRPCClient <AppRouter >({links : [httpBatchStreamLink ({url : 'http://localhost:3000',}),],});constiterable = awaittrpc .examples .iterable .query ();for await (constvalue ofiterable ) {console .log ('Iterable:',value );}
ts// @filename: server.tsimport {publicProcedure ,router } from './trpc';constappRouter =router ({examples : {iterable :publicProcedure .query (async function* () {for (leti = 0;i < 3;i ++) {await newPromise ((resolve ) =>setTimeout (resolve , 500));yieldi ;}}),},});export typeAppRouter = typeofappRouter ;// @filename: client.tsimport {createTRPCClient ,httpBatchStreamLink } from '@trpc/client';import type {AppRouter } from './server';consttrpc =createTRPCClient <AppRouter >({links : [httpBatchStreamLink ({url : 'http://localhost:3000',}),],});constiterable = awaittrpc .examples .iterable .query ();for await (constvalue ofiterable ) {console .log ('Iterable:',value );}
互換性(クライアント側)
ブラウザ
ブラウザサポートはfetchのサポートと同一である必要があります。
Node.js / Deno
ブラウザ以外のランタイムでは、fetch実装がストリーミングをサポートしている必要があります。つまりawait fetch(...)で得られるレスポンスのbodyプロパティがReadableStream<Uint8Array> | NodeJS.ReadableStream型であることを意味し、以下いずれかの条件を満たします:
-
response.body.getReaderがReadableStreamDefaultReader<Uint8Array>オブジェクトを返す関数である -
または
response.bodyがUint8ArrayのBufferである
これにはundici、node-fetch、ネイティブNode.js fetch実装、WebAPI fetch実装(ブラウザ)のサポートが含まれます。
React Native
ストリームの受信にはTextDecoderおよびTextDecoderStream APIが必要ですが、React Nativeでは利用できません。重要な注意点として、TextDecoderStreamのポリフィルが自動的にReadableStreamおよびWritableStreamをポリフィルしない場合、これらも追加でポリフィルする必要があります。ストリーミングを有効化するにはこれらのポリフィルが必須です。
また、httpBatchStreamLinkの設定オプションでデフォルトのfetchをオーバーライドする必要があります。以下の例では、fetchの実装にExpo fetchパッケージを使用します。
typescripthttpBatchStreamLink({fetch: (url, opts) =>fetch(url, {...opts,reactNative: { textStreaming: true },}),...restOfConfig,});
typescripthttpBatchStreamLink({fetch: (url, opts) =>fetch(url, {...opts,reactNative: { textStreaming: true },}),...restOfConfig,});
互換性(サーバーサイド)
⚠️ AWS Lambdaでは、
httpBatchStreamLinkはサポートされていません(通常のhttpBatchLinkのように動作します)。有効にしても問題は発生しませんが、効果はありません。
⚠️ Cloudflare Workersでは、
ReadableStreamAPIを機能フラグstreams_enable_constructorsを通じて有効にする必要があります。
参考
このリンクのソースコードはGitHubで確認できます。
接続を維持するためのpingオプションの設定
ルート設定を行う際に、jsonlオプションを渡して接続を維持するためのpingオプションを設定できます。
tsimport { initTRPC } from '@trpc/server';const t = initTRPC.create({jsonl: {pingMs: 1000,},});
tsimport { initTRPC } from '@trpc/server';const t = initTRPC.create({jsonl: {pingMs: 1000,},});