비 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에서는 tRPC 클라이언트 링크에도 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,};}),});