HTTP バッチストリームリンク
unstable_httpBatchStreamLink
は、個々の tRPC 操作の配列を単一の HTTP リクエストにバッチ処理し、単一の tRPC プロシージャに送信するターミネーションリンクです(httpBatchLink
と同等)。ただし、バッチのすべてのレスポンスの準備が完了するのを待たず、データが利用可能になり次第すぐにレスポンスをストリーミングします。
これは新しいAPIであるため、unstable_
というプレフィックスを付けていますが、安全に使用できます! 詳細はこちら。
使用方法
使用方法とオプションはすべて
httpBatchLink
と同じです。
プロシージャ内でレスポンスヘッダー(Cookieを含む)を変更/設定する必要がある場合は、代わりにhttpBatchLink
を使用してください!これは、unstable_httpBatchStreamLink
はストリームが開始されるとヘッダーの設定をサポートしないためです。詳細はこちら。
httpBatchStreamLink
をインポートし、links
配列に追加することができます
client/index.tsts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
client/index.tsts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
その後、すべてのプロシージャをPromise.all
に設定することで、バッチ処理を利用できます。以下のコードは、HTTPリクエストを正確に1つ、サーバーではデータベースクエリを正確に1つ生成します。
ts
const somePosts = await Promise.all([trpc.post.byId.query(1),trpc.post.byId.query(2),trpc.post.byId.query(3),]);
ts
const somePosts = await Promise.all([trpc.post.byId.query(1),trpc.post.byId.query(2),trpc.post.byId.query(3),]);
ストリーミングモード
⚠️ このリンクは不安定であり、将来変更される可能性があります。
リクエストをまとめてバッチ処理する場合、通常のhttpBatchLink
の動作は、すべてのリクエストが完了するまで待ってからレスポンスを送信することです。レスポンスの準備ができた時点で送信する場合は、代わりにhttpBatchStreamLink
を使用できます。これは、長時間実行されるリクエストに役立ちます。
client/index.tsts
import { createTRPCClient, unstable_httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [unstable_httpBatchStreamLink({url: 'http://localhost:3000',}),],});
client/index.tsts
import { createTRPCClient, unstable_httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [unstable_httpBatchStreamLink({url: 'http://localhost: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
がUint8Array
Buffer
であるかのどちらかです。
これには、undici
、node-fetch
、ネイティブNode.js fetch実装、およびWebAPI fetch実装(ブラウザ)のサポートが含まれます。
React Native
ストリームの受信はTextDecoder
APIに依存しており、React Nativeでは使用できません。それでもストリーミングを有効にする場合は、ポリフィルを使用し、httpBatchStreamLink
オプションに渡すことができます。
ts
unstable_httpBatchStreamLink({url: 'http://localhost:3000',textDecoder: new TextDecoder(),// ^? textDecoder: { decode: (input: Uint8Array) => string }});
ts
unstable_httpBatchStreamLink({url: 'http://localhost:3000',textDecoder: new TextDecoder(),// ^? textDecoder: { decode: (input: Uint8Array) => string }});
互換性(サーバー側)
⚠️ AWS Lambdaでは、
unstable_httpBatchStreamLink
はサポートされていません(通常のhttpBatchLink
のように動作します)。有効にしても問題はありませんが、効果はありません。
⚠️ Cloudflare Workersでは、機能フラグを使用して
ReadableStream
APIを有効にする必要があります:streams_enable_constructors
参照
このリンクのソースコードはGitHubで確認できます。