tRPC v11 발표
이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →
tRPC v11은 @next 태그를 통해 오랫동안 프로덕션 준비 완료 상태였지만, 우리는 시맨틱 버저닝에 지나치게 얽매이지 않고 새로운 기능을 추가하는 데 집중해 왔습니다. 오늘, 우리는 마침내 tRPC v11의 공식 릴리즈를 발표하게 되어 기쁘게 생각합니다!
2022년 11월 마지막 메이저 버전 릴리즈 이후, tRPC 커뮤니티는 상당한 성장을 이루었습니다:
-
현재 GitHub에서 35,000개 이상의 스타를 보유하고 있습니다
-
5,000명 이상의 멤버가 있는 Discord 커뮤니티
tRPC v11의 출시와 함께, @next 채널에서의 안정적인 발전 덕분에 v11이 이미 많은 대형 TypeScript 프로젝트에서 프로덕션 환경에서 사용되고 있음을 알리게 되어 기쁩니다.
새 프로젝트의 경우 tRPC v11에 대해 알아보기 위해 예제 애플리케이션을 통해 시작할 수 있습니다. 아직 tRPC v10을 사용 중인 프로젝트의 경우 v11 마이그레이션 가이드를 참조하세요.
변경 사항 개요
v11은 v10과 대체로 하위 호환성이 있지만, 많은 새로운 기능과 개선 사항을 가져옵니다. 주요 내용은 다음과 같습니다:
TanStack Query v5 지원
TanStack Query v5가 출시되면서 tRPC의 react-query 통합에 몇 가지 주요 변경 사항이 필요해졌습니다. 이는 @next 태그를 통해 꽤 이른 시점부터 사용 가능했지만, 이제 공식적으로 릴리즈되었습니다. 많은 프로젝트에서 이미 업그레이드를 선택했으며, 전체 React Suspense 지원 및 기타 많은 개선 사항의 이점을 누리고 있습니다. tRPC React 클라이언트 코드 마이그레이션에 대한 지침은 TanStack Query의 마이그레이션 가이드를 참조하세요.
새로운 TanStack React Query 통합
FormData/비 JSON 콘텐츠 타입 지원
가장 많이 요청된 기능 중 하나는 단순히 JSON 데이터 이상을 주고받을 수 있는 기능입니다. tRPC v11을 통해 이제 다양한 비 JSON 콘텐츠 타입, FormData, 그리고 Blob, File, Uint8Array와 같은 바이너리 타입의 데이터를 주고받을 수 있습니다. 이러한 콘텐츠 타입 사용 방법에 대한 예제는 여기에서 확인할 수 있습니다.
tsimport {publicProcedure ,router } from './trpc';import {octetInputParser } from '@trpc/server/http';import {z } from 'zod';constappRouter =router ({formData :publicProcedure .input (z .instanceof (FormData )).mutation (async ({input }) => {}),file :publicProcedure .input (octetInputParser ).mutation (async ({input }) => {}),});
tsimport {publicProcedure ,router } from './trpc';import {octetInputParser } from '@trpc/server/http';import {z } from 'zod';constappRouter =router ({formData :publicProcedure .input (z .instanceof (FormData )).mutation (async ({input }) => {}),file :publicProcedure .input (octetInputParser ).mutation (async ({input }) => {}),});
React Server Components/Next.js App Router
Next.js App Router와 함께 tRPC를 사용하는 것은 처음부터 가능했으며, 다음 두 가지 방법 중 하나를 사용할 수 있습니다:
-
비동기/대기를 사용하는 서버 중심 접근 방식:
createCaller또는createTRPCClient -
또는 React Query 통합과 클라이언트 사이드 훅을 사용하는 클라이언트 중심 접근 방식
이 두 방식 사이의 연동은 다소 깔끔하지 않았습니다. 서로 다른 데이터 패칭 패턴을 유지해야 할 때 재검증 패턴이 혼합되어 개발자 경험이 tRPC의 기준에 미치지 못하는 상황이었습니다.
이 문제를 해결하기 위해 React Server Components(RSC) 지원을 개선하고, 서버에서만 실행되는 RSC의 힘을 React Query의 동적 클라이언트 측 캐시와 결합하여 활용하기 쉽도록 프리페치 헬퍼를 추가했습니다. 이제 서버 측 RSC에서 프로시저 실행을 시작하고, 클라이언트 측에서 보류 중인 프로미스를 이어받아 React Query 캐시를 자동으로 하이드레이트할 수 있습니다. 이를 통해 서버-클라이언트 간 워터폴 문제 없이 고도로 동적인 애플리케이션을 구축할 수 있습니다. 자세한 내용은 서버 컴포넌트 문서에서 확인하세요.
이 새로운 프리페치 패턴 외에도 서버 함수에 대한 실험적 지원을 추가했습니다. 자세한 내용은 블로그 포스트에서 확인할 수 있습니다. 서버 함수가 생태계에서 더 확립된 패턴이 될수록 이 기능을 계속 개선할 계획입니다.
또한 TanStack 팀과 협력하여 서버 함수 API 설계를 지원했습니다. 목표는 tRPC의 강력한 미들웨어 시스템 일부를 분리하여 생태계 전반에서 사용할 수 있는 별도 패키지로 제공하는 것입니다.
쿼리 및 뮤테이션의 스트리밍 응답
쿼리 응답을 스트리밍할 수 있는 httpBatchStreamLink를 도입했습니다. 대규모 데이터셋을 다루거나 실시간으로 데이터를 처리하며 프론트엔드에 전달해야 할 때 유용합니다. 이는 구독(subscription)을 대체하는 것이 아니라 도구 상자에 추가되는 또 다른 옵션입니다.
ts// @filename: server.tsimport {publicProcedure ,router } from './trpc';constappRouter =router ({examples : {iterable :publicProcedure .query (async function* () {leti = 0;while (true) {await newPromise ((resolve ) =>setTimeout (resolve , 500));yieldi ++;}}),},});export typeAppRouter = typeofappRouter ;// @filename: client.tsimport {createTRPCClient ,httpBatchStreamLink } from '@trpc/client';import type {AppRouter } from './server';consttrpc =createTRPCClient <AppRouter >({links : [httpBatchStreamLink ({url : 'http://localhost:3000',}),],});constiterable = awaittrpc .examples .iterable .query ();for await (constvalue ofiterable ) {console .log ('Iterable:',value );}
ts// @filename: server.tsimport {publicProcedure ,router } from './trpc';constappRouter =router ({examples : {iterable :publicProcedure .query (async function* () {leti = 0;while (true) {await newPromise ((resolve ) =>setTimeout (resolve , 500));yieldi ++;}}),},});export typeAppRouter = typeofappRouter ;// @filename: client.tsimport {createTRPCClient ,httpBatchStreamLink } from '@trpc/client';import type {AppRouter } from './server';consttrpc =createTRPCClient <AppRouter >({links : [httpBatchStreamLink ({url : 'http://localhost:3000',}),],});constiterable = awaittrpc .examples .iterable .query ();for await (constvalue ofiterable ) {console .log ('Iterable:',value );}
라우터 정의 단축 표현
라우트 정의 프로세스를 단순화하기 위해 새로운 단축 문법을 도입했습니다. 문서
tsconst appRouter = router({// Shorthand plain object for creating a sub-routernested1: {proc: publicProcedure.query(() => '...'),},// Equivalent of:nested2: router({proc: publicProcedure.query(() => '...'),}),});
tsconst appRouter = router({// Shorthand plain object for creating a sub-routernested1: {proc: publicProcedure.query(() => '...'),},// Equivalent of:nested2: router({proc: publicProcedure.query(() => '...'),}),});
구독: 서버 발송 이벤트 및 기타 개선
-
tRPC v11은 서버 발송 이벤트(SSE)를 사용한 구독 처리 방식을 새롭게 도입했습니다. 복잡한 WebSocket 없이 실시간 업데이트를 처리하는 훌륭한 방법으로, 향후 우선적으로 사용할 것을 권장합니다.
-
구독에서 자바스크립트 제너레이터 사용을 지원합니다. 이를 통해 시간 경과에 따라 여러 값을 생성하고 완료 시 정리 작업을 수행할 수 있는 복잡한 구독 핸들러를 매우 JS 스타일로 작성할 수 있습니다.
-
구독이 출력 유효성 검사를 지원하여 구독 핸들러의 타입 안전성이 개선되었습니다.
v9 .interop() 모드 지원 종료
tRPC v10에서는 v9 사용자의 원활한 마이그레이션을 위해 .interop() 모드를 도입했습니다. tRPC v11에서는 .interop() 모드를 제거했습니다. 여전히 .interop() 모드를 사용 중이라면 v10 마이그레이션 가이드를 참조하여 현행 tRPC API로 전환을 완료하세요.
v11로 마이그레이션
현재 tRPC v10을 사용 중이라면 마이그레이션 가이드를 따라 v11로 업그레이드할 수 있습니다. 마이그레이션 가이드에는 v11의 모든 주요 변경 사항과 신규 기능이 포함되어 있습니다.
감사합니다!
tRPC 코어 팀을 대표하여 tRPC를 사용하고 지원해 주신 모든 분께 감사드립니다.
-
트위터에서 @trpcio 팔로우
-
Discord 커뮤니티 참여