콘텐츠 타입
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와 같은 오류가 발생하는 경우, tRPC가 처리하기 전에 서버(예: Express, Next.js)가 요청 본문을 파싱하지 않도록 확인하세요.
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는 많은 octet 콘텐츠 타입을 프로시저에서 소비할 수 있는 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,};}),});