JSON以外のコンテンツタイプ
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
JSONとしてシリアライズ可能なデータに加えて、tRPCはプロシージャの入力としてFormData、File、その他のバイナリタイプを使用できます
クライアント側の設定
tRPCは複数の非JSONシリアライズ可能な型をネイティブサポートしていますが、クライアント側では設定に応じてリンクの設定を若干調整する必要がある場合があります。
httpLinkは非JSONコンテンツタイプを標準でサポートしています。このリンクのみを使用している場合、既存の設定は即座に動作します
tsimport { httpLink } from '@trpc/client';trpc.createClient({links: [httpLink({url: 'http://localhost:2022',}),],});
tsimport { httpLink } from '@trpc/client';trpc.createClient({links: [httpLink({url: 'http://localhost:2022',}),],});
ただし、すべてのリンクがこれらの新しいコンテンツタイプをサポートしているわけではありません。httpBatchLinkやhttpBatchStreamLinkを使用している場合は、splitLinkを追加し、コンテンツに応じて使用するリンクを判別する必要があります
tsimport {httpBatchLink,httpLink,isNonJsonSerializable,splitLink,} from '@trpc/client';trpc.createClient({links: [splitLink({condition: (op) => isNonJsonSerializable(op.input),true: httpLink({url,}),false: httpBatchLink({url,}),}),],});
tsimport {httpBatchLink,httpLink,isNonJsonSerializable,splitLink,} from '@trpc/client';trpc.createClient({links: [splitLink({condition: (op) => isNonJsonSerializable(op.input),true: httpLink({url,}),false: httpBatchLink({url,}),}),],});
tRPCサーバーでtransformerを使用している場合、TypeScriptではクライアントリンクでもtransformerを定義する必要があります。
以下の例をベースとして使用してください:
tsimport {httpBatchLink,httpLink,isNonJsonSerializable,splitLink,} from '@trpc/client';import superjson from 'superjson';trpc.createClient({links: [splitLink({condition: (op) => isNonJsonSerializable(op.input),true: httpLink({url,transformer: {// request - convert data before sending to the tRPC serverserialize: (data) => data,// response - convert the tRPC response before using it in clientdeserialize: superjson.deserialize, // or your other transformer},}),false: httpBatchLink({url,transformers: superjson, // or your other transformer}),}),],});
tsimport {httpBatchLink,httpLink,isNonJsonSerializable,splitLink,} from '@trpc/client';import superjson from 'superjson';trpc.createClient({links: [splitLink({condition: (op) => isNonJsonSerializable(op.input),true: httpLink({url,transformer: {// request - convert data before sending to the tRPC serverserialize: (data) => data,// response - convert the tRPC response before using it in clientdeserialize: superjson.deserialize, // or your other transformer},}),false: httpBatchLink({url,transformers: superjson, // or your other transformer}),}),],});
サーバー側の使用方法
tRPCがリクエストを処理する際、リクエストのContent-Typeヘッダーに基づいてリクエストボディの解析を行います。
Failed to parse body as XXXのようなエラーが発生した場合は、サーバー(例: Express, Next.js)がtRPCが処理する前にリクエストボディを解析していないことを確認してください。
ts// Example in express// incorrectconst app = express();app.use(express.json()); // this try to parse body before tRPC.app.post('/express/hello', (req,res) => {/* ... */ }); // normal express route handlerapp.use('/trpc', trpcExpress.createExpressMiddleware({ /* ... */}))// tRPC fails to parse body// correctconst app = express();app.use('/express', express.json()); // do it only in "/express/*" pathapp.post('/express/hello', (req,res) => {/* ... */ });app.use('/trpc', trpcExpress.createExpressMiddleware({ /* ... */}))// tRPC can parse body
ts// Example in express// incorrectconst app = express();app.use(express.json()); // this try to parse body before tRPC.app.post('/express/hello', (req,res) => {/* ... */ }); // normal express route handlerapp.use('/trpc', trpcExpress.createExpressMiddleware({ /* ... */}))// tRPC fails to parse body// correctconst app = express();app.use('/express', express.json()); // do it only in "/express/*" pathapp.post('/express/hello', (req,res) => {/* ... */ });app.use('/trpc', trpcExpress.createExpressMiddleware({ /* ... */}))// tRPC can parse body
FormData入力
FormDataはネイティブでサポートされています。より高度な使用方法として、zod-form-dataのようなライブラリと組み合わせて、型安全な方法で入力を検証することもできます
tsimport {z } from 'zod';export constt =initTRPC .create ();constpublicProcedure =t .procedure ;export constappRouter =t .router ({hello :publicProcedure .input (z .instanceof (FormData )).mutation ((opts ) => {constdata =opts .input ;return {greeting : `Hello ${data .get ('name')}`,};}),});
tsimport {z } from 'zod';export constt =initTRPC .create ();constpublicProcedure =t .procedure ;export constappRouter =t .router ({hello :publicProcedure .input (z .instanceof (FormData )).mutation ((opts ) => {constdata =opts .input ;return {greeting : `Hello ${data .get ('name')}`,};}),});
より高度なコードサンプルについては、こちらのサンプルプロジェクトをご覧ください
Fileおよびその他のバイナリタイプ入力
tRPCは多くのオクテットコンテンツタイプをReadableStreamに変換し、プロシージャ内で利用できるようにします。現在サポートされているのはBlob、Uint8Array、Fileです
tsimport {octetInputParser } from '@trpc/server/http';export constt =initTRPC .create ();constpublicProcedure =t .procedure ;export constappRouter =t .router ({upload :publicProcedure .input (octetInputParser ).mutation ((opts ) => {constdata =opts .input ;return {valid : true,};}),});
tsimport {octetInputParser } from '@trpc/server/http';export constt =initTRPC .create ();constpublicProcedure =t .procedure ;export constappRouter =t .router ({upload :publicProcedure .input (octetInputParser ).mutation ((opts ) => {constdata =opts .input ;return {valid : true,};}),});