Tipos de Contenido No JSON
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Además de datos serializables en JSON, tRPC puede usar FormData, File y otros tipos binarios como entradas para procedimientos.
Configuración del Cliente
Aunque tRPC soporta nativamente varios tipos no serializables en JSON, tu cliente podría necesitar una pequeña configuración de links para admitirlos dependiendo de tu configuración.
httpLink soporta tipos de contenido no JSON directamente. Si solo usas este, tu configuración existente funcionará inmediatamente.
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',}),],});
Sin embargo, no todos los links soportan estos nuevos tipos de contenido. Si usas httpBatchLink o httpBatchStreamLink, necesitarás incluir un splitLink y decidir qué link usar según el contenido.
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,}),}),],});
Si usas transformer en tu servidor tRPC, TypeScript requiere que tu link del cliente tRPC también defina transformer.
Usa este ejemplo como base:
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}),}),],});
Uso en el Servidor
Cuando tRPC maneja una solicitud, se encarga de analizar el cuerpo de la misma basándose en el encabezado Content-Type.
Si encuentras errores como Failed to parse body as XXX, asegúrate de que tu servidor (por ejemplo, Express, Next.js) no esté analizando el cuerpo antes de que tRPC lo maneje.
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
Entrada FormData
FormData tiene soporte nativo. Para usos más avanzados, puedes combinarlo con bibliotecas como zod-form-data para validar entradas de forma tipada.
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')}`,};}),});
Para un ejemplo de código más avanzado, consulta nuestro proyecto de ejemplo aquí
Entradas File y Otros Tipos Binarios
tRPC convierte muchos tipos de contenido octet a un ReadableStream que puede consumirse en un procedimiento. Actualmente estos incluyen Blob, Uint8Array y 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,};}),});