コンテンツタイプ
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
tRPCは複数のコンテンツタイプをプロシージャ入力としてサポートします:JSONシリアライズ可能なデータ、FormData、File、Blob、その他のバイナリタイプです。
JSON(デフォルト)
デフォルトでは、tRPCはJSONシリアライズ可能なデータを送受信します。追加設定は不要で、JSONにシリアライズ可能なあらゆる入力がすべてのリンク(httpLink、httpBatchLink、httpBatchStreamLink)でそのまま動作します。
tsimport {z } from 'zod';export constt =initTRPC .create ();constpublicProcedure =t .procedure ;export constappRouter =t .router ({hello :publicProcedure .input (z .object ({name :z .string () })).query ((opts ) => {return {greeting : `Hello ${opts .input .name }` };}),});
tsimport {z } from 'zod';export constt =initTRPC .create ();constpublicProcedure =t .procedure ;export constappRouter =t .router ({hello :publicProcedure .input (z .object ({name :z .string () })).query ((opts ) => {return {greeting : `Hello ${opts .input .name }` };}),});
非JSONコンテンツタイプ
JSONに加えて、tRPCはFormData、File、その他のバイナリタイプをプロシージャ入力として使用できます。
クライアント設定
tRPCはいくつかの非JSONシリアライズ可能なタイプをネイティブでサポートしていますが、クライアント側では設定に応じてリンクの設定が少し必要になる場合があります。
httpLinkは非JSONコンテンツタイプをそのままサポートしています。このリンクのみを使用している場合、既存の設定はすぐに動作するはずです。
tsimport {createTRPCClient ,httpLink } from '@trpc/client';import type {AppRouter } from './server';createTRPCClient <AppRouter >({links : [httpLink ({url : 'http://localhost:2022',}),],});
tsimport {createTRPCClient ,httpLink } from '@trpc/client';import type {AppRouter } from './server';createTRPCClient <AppRouter >({links : [httpLink ({url : 'http://localhost:2022',}),],});
ただし、すべてのリンクがこれらのコンテンツタイプをサポートしているわけではありません。httpBatchLinkやhttpBatchStreamLinkを使用している場合、splitLinkを含めてリクエストをコンテンツタイプに基づいてルーティングする必要があります。
tsimport {createTRPCClient ,httpBatchLink ,httpLink ,isNonJsonSerializable ,splitLink ,} from '@trpc/client';import type {AppRouter } from './server';consturl = 'http://localhost:2022';createTRPCClient <AppRouter >({links : [splitLink ({condition : (op ) =>isNonJsonSerializable (op .input ),true :httpLink ({url ,}),false :httpBatchLink ({url ,}),}),],});
tsimport {createTRPCClient ,httpBatchLink ,httpLink ,isNonJsonSerializable ,splitLink ,} from '@trpc/client';import type {AppRouter } from './server';consturl = 'http://localhost:2022';createTRPCClient <AppRouter >({links : [splitLink ({condition : (op ) =>isNonJsonSerializable (op .input ),true :httpLink ({url ,}),false :httpBatchLink ({url ,}),}),],});
tRPCサーバーでtransformerを使用している場合、TypeScriptではtRPCクライアントのリンクでもtransformerを定義する必要があります。
以下の例をベースにしてください:
tsimport {createTRPCClient ,httpBatchLink ,httpLink ,isNonJsonSerializable ,splitLink ,} from '@trpc/client';importsuperjson from 'superjson';import type {AppRouter } from './server';consturl = 'http://localhost:2022';createTRPCClient <AppRouter >({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 : (data ) =>superjson .deserialize (data ), // or your other transformer},}),false :httpBatchLink ({url ,transformer :superjson , // or your other transformer}),}),],});
tsimport {createTRPCClient ,httpBatchLink ,httpLink ,isNonJsonSerializable ,splitLink ,} from '@trpc/client';importsuperjson from 'superjson';import type {AppRouter } from './server';consturl = 'http://localhost:2022';createTRPCClient <AppRouter >({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 : (data ) =>superjson .deserialize (data ), // or your other transformer},}),false :httpBatchLink ({url ,transformer :superjson , // or your other transformer}),}),],});
サーバー設定
tRPCがリクエストを処理する際、リクエストのContent-Typeヘッダーに基づいてリクエストボディの解析を行います。
Failed to parse body as XXXのようなエラーが発生した場合、サーバー(例:Express、Next.js)がtRPCの処理前にリクエストボディを解析していないことを確認してください。
ts// Example in expressimportexpress from 'express';import * astrpcExpress from '@trpc/server/adapters/express';import {appRouter } from './router';// incorrectconstapp1 =express ();app1 .use (express .json ()); // this tries to parse body before tRPC.app1 .post ('/express/hello', (req ,res ) => {res .end (); }); // normal express route handlerapp1 .use ('/trpc',trpcExpress .createExpressMiddleware ({router :appRouter })); // tRPC fails to parse body// correctconstapp2 =express ();app2 .use ('/express',express .json ()); // do it only in "/express/*" pathapp2 .post ('/express/hello', (req ,res ) => {res .end (); });app2 .use ('/trpc',trpcExpress .createExpressMiddleware ({router :appRouter })); // tRPC can parse body
ts// Example in expressimportexpress from 'express';import * astrpcExpress from '@trpc/server/adapters/express';import {appRouter } from './router';// incorrectconstapp1 =express ();app1 .use (express .json ()); // this tries to parse body before tRPC.app1 .post ('/express/hello', (req ,res ) => {res .end (); }); // normal express route handlerapp1 .use ('/trpc',trpcExpress .createExpressMiddleware ({router :appRouter })); // tRPC fails to parse body// correctconstapp2 =express ();app2 .use ('/express',express .json ()); // do it only in "/express/*" pathapp2 .post ('/express/hello', (req ,res ) => {res .end (); });app2 .use ('/trpc',trpcExpress .createExpressMiddleware ({router :appRouter })); // 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,};}),});