본문 바로가기
Frontend2026년 5월 28일4분 읽기

tRPC 12 + Server Actions — RSC 환경에서 통합 패턴 정리

YS
김영삼
조회 277
tRPC 12 + Server Actions — RSC 환경에서 통합 패턴 정리

핵심 요약

tRPC 12가 RSC(Server Components)와 정식 통합. 같은 procedure를 client useQuery·Server Action·RSC 직접 호출 3가지 방식으로 호출 가능. 사내 18 procedure 마이그레이션 후 코드 28% 감소, 타입 안정성 100%.

1. RSC 직접 호출 — caller pattern

// server/trpc.ts
import { createCallerFactory } from '@trpc/server'
import { appRouter } from './routers/_app'
export const createCaller = createCallerFactory(appRouter)

// app/posts/page.tsx (RSC)
import { createCaller } from '@/server/trpc'
import { cookies } from 'next/headers'
export default async function Page() {
  const caller = createCaller({ session: await getSession(cookies()) })
  const posts = await caller.post.list({ limit: 20 })
  return 
}

HTTP 왕복 없이 RSC에서 procedure 직접 호출 — request waterfall 1단계 단축.

2. Server Action 패턴

// app/actions.ts
'use server'
import { createCaller } from '@/server/trpc'

export async function createPostAction(formData: FormData) {
  const caller = createCaller(await getCtx())
  return caller.post.create({
    title: formData.get('title') as string,
    body: formData.get('body') as string,
  })
}

form action 그대로, procedure 한 번 정의로 client·server·RSC 모두 사용.

3. Streaming subscriptions — SSE

12.0에서 subscriptions가 SSE 표준. WebSocket 의존 제거. Edge runtime 호환.

4. 마이그레이션 효과

지표Before(REST+tRPC 11)After(tRPC 12)
코드 줄수18,40013,250
타입 에러(런타임)월 ~12건0
p99 응답(서버)180ms82ms

5. 함정

  • createCaller 컨텍스트 누락 — RSC에서 ctx 빠뜨리면 권한 검사 통과, 보안 사고. middleware 명시
  • Server Action revalidation — caller.x.create() 후 revalidatePath 수동 호출 필요
  • Suspense boundary — caller가 throw하면 nearest error boundary로, fallback 설계
  • Client component에서 caller 호출 금지 — 빌드 통과하지만 런타임 에러

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록