Types de contenu
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
tRPC prend en charge plusieurs types de contenu comme entrées de procédure : données sérialisables en JSON, FormData, File, Blob et autres types binaires.
JSON (par défaut)
Par défaut, tRPC envoie et reçoit des données sérialisables en JSON. Aucune configuration supplémentaire n'est nécessaire — toute entrée pouvant être sérialisée en JSON fonctionne immédiatement avec tous les liens (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 }` };}),});
Types de contenu non-JSON
En complément du JSON, tRPC peut utiliser FormData, File et d'autres types binaires comme entrées de procédure.
Configuration client
Bien que tRPC prenne nativement en charge plusieurs types non sérialisables en JSON, votre client peut nécessiter une légère configuration des liens selon votre installation.
httpLink prend en charge les types de contenu non-JSON immédiatement — si vous utilisez uniquement ce lien, votre configuration existante devrait fonctionner sans modification.
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',}),],});
Cependant, tous les liens ne prennent pas en charge ces types de contenu. Si vous utilisez httpBatchLink ou httpBatchStreamLink, vous devrez inclure un splitLink et router les requêtes selon le type de contenu.
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 ,}),}),],});
Si vous utilisez transformer dans votre serveur tRPC, TypeScript exige que le lien de votre client tRPC définisse également transformer.
Utilisez cet exemple comme base :
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}),}),],});
Configuration serveur
Lorsqu'une requête est traitée par tRPC, il analyse le corps de la requête en fonction de l'en-tête Content-Type.
Si vous rencontrez des erreurs comme Failed to parse body as XXX, assurez-vous que votre serveur (ex : Express, Next.js) n'analyse pas le corps de la requête avant que tRPC ne le traite.
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
Entrée FormData
FormData est pris en charge nativement. Pour des usages avancés, vous pouvez le combiner avec une bibliothèque comme zod-form-data pour valider les entrées de manière typée.
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')}`,};}),});
Pour un exemple de code plus avancé, consultez notre projet d'exemple ici
Entrées File et autres types binaires
tRPC convertit de nombreux types de contenu octet en ReadableStream utilisable dans une procédure. Actuellement, cela inclut Blob, Uint8Array et 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,};}),});