HTTP バッチストリームリンク
unstable_httpBatchStreamLink は、個々の tRPC 操作の配列を単一の HTTP リクエストにバッチ処理し、単一の tRPC プロシージャに送信するターミネーションリンクです(httpBatchLinkと同等)。ただし、バッチのすべてのレスポンスの準備が完了するのを待たず、データが利用可能になり次第すぐにレスポンスをストリーミングします。
これは新しいAPIであるため、unstable_というプレフィックスを付けていますが、安全に使用できます! 詳細はこちら。
使用方法
使用方法とオプションはすべて
httpBatchLinkと同じです。
プロシージャ内でレスポンスヘッダー(Cookieを含む)を変更/設定する必要がある場合は、代わりにhttpBatchLinkを使用してください!これは、unstable_httpBatchStreamLinkはストリームが開始されるとヘッダーの設定をサポートしないためです。詳細はこちら。
httpBatchStreamLinkをインポートし、links配列に追加することができます
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'https://:3000',}),],});
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'https://:3000',}),],});
その後、すべてのプロシージャをPromise.allに設定することで、バッチ処理を利用できます。以下のコードは、HTTPリクエストを正確に1つ、サーバーではデータベースクエリを正確に1つ生成します。
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, unstable_httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [unstable_httpBatchStreamLink({url: 'https://:3000',}),],});
client/index.tstsimport { createTRPCClient, unstable_httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [unstable_httpBatchStreamLink({url: 'https://:3000',}),],});
通常のhttpBatchLinkと比較して、unstable_httpBatchStreamLinkは
- リクエストを
Trpc-Batch-Mode: streamヘッダーで送信するようにします。 - レスポンスを
Transfer-Encoding: chunkedおよびVary: trpc-batch-modeヘッダーで送信するようにします。 responseMetaに渡される引数オブジェクトからdataキーを削除します(ストリーミングされたレスポンスでは、ヘッダーはデータが利用可能になる前に送信されるため)。
互換性(クライアント側)
ブラウザ
ブラウザのサポートはfetchのサポートと同じです。
Node.js / Deno
ブラウザ以外のランタイムの場合、fetchの実装はストリーミングをサポートしている必要があります。つまり、await fetch(...)によって取得されたレスポンスには、bodyプロパティ(ReadableStream<Uint8Array> | NodeJS.ReadableStream型)があり、
response.body.getReaderがReadableStreamDefaultReader<Uint8Array>オブジェクトを返す関数であるかresponse.bodyがUint8ArrayBufferであるかのどちらかです。
これには、undici、node-fetch、ネイティブNode.js fetch実装、およびWebAPI fetch実装(ブラウザ)のサポートが含まれます。
React Native
ストリームの受信はTextDecoder APIに依存しており、React Nativeでは使用できません。それでもストリーミングを有効にする場合は、ポリフィルを使用し、httpBatchStreamLinkオプションに渡すことができます。
tsunstable_httpBatchStreamLink({url: 'https://:3000',textDecoder: new TextDecoder(),// ^? textDecoder: { decode: (input: Uint8Array) => string }});
tsunstable_httpBatchStreamLink({url: 'https://:3000',textDecoder: new TextDecoder(),// ^? textDecoder: { decode: (input: Uint8Array) => string }});
互換性(サーバー側)
⚠️ AWS Lambdaでは、
unstable_httpBatchStreamLinkはサポートされていません(通常のhttpBatchLinkのように動作します)。有効にしても問題はありませんが、効果はありません。
⚠️ Cloudflare Workersでは、機能フラグを使用して
ReadableStreamAPIを有効にする必要があります:streams_enable_constructors
参照
このリンクのソースコードはGitHubで確認できます。