1. 배경과 탄생 배경
웹 개발의 역사에서 API 설계 방법론은 끊임없이 진화해 왔습니다. 가장 먼저 2000년대 초반 로이 필딩에 의해 정립된 REST(Representational State Transfer)는 HTTP 프로토콜의 자원을 활용하여 상태를 주고받는 방식으로, 웹의 표준으로 자리 잡았습니다. 하지만 모바일 환경이 복잡해지고 데이터 요구사항이 세분화되면서 REST의 고정된 엔드포인트 방식은 오버페칭(Over-fetching)과 언더페칭(Under-fetching)이라는 한계에 직면했습니다. 이를 해결하기 위해 2015년 페이스북은 클라이언트가 필요한 데이터의 구조를 직접 정의할 수 있는 GraphQL을 오픈소스로 공개하며 선언적 데이터 페칭의 시대를 열었습니다.
최근에는 TypeScript의 보급과 함께 tRPC가 급부상하고 있습니다. 과거에는 백엔드와 프런트엔드 사이의 타입 동기화를 위해 Swagger나 GraphQL Code Generator 같은 복잡한 코드 생성 도구가 필요했습니다. 하지만 tRPC는 별도의 스키마 정의나 코드 생성 단계 없이, 서버의 함수 타입을 클라이언트에서 그대로 추론하여 사용할 수 있게 함으로써 개발 생산성을 극대화했습니다. 특히 Vite 5.x나 React 19와 같은 최신 프레임워크 생태계와 결합하여 모노레포 환경에서 강력한 힘을 발휘하고 있습니다. 이러한 변화는 단순히 기술적 유행을 넘어, 개발자가 비즈니스 로직에만 집중할 수 있는 환경을 구축하려는 노력의 산물입니다.
2. 핵심 차이점
이 세 가지 기술의 가장 큰 차이점은 데이터 전송 모델과 타입 시스템의 구현 방식에 있습니다. REST는 자원(Resource) 중심적이며, URL과 HTTP 메서드(GET, POST, PUT, DELETE)를 통해 동작을 정의합니다. 이는 매우 직관적이지만 데이터 구조가 변경될 때마다 새로운 엔드포인트를 만들거나 버전 관리를 해야 하는 번거로움이 있습니다. 반면 GraphQL은 그래프 구조를 기반으로 하며, 클라이언트가 런타임에 쿼리를 작성하여 서버에 전달합니다. 서버는 스키마를 통해 데이터의 형태를 정의하고, 클라이언트는 그 안에서 자유롭게 데이터를 조합할 수 있습니다.
tRPC는 이들과는 완전히 다른 접근 방식을 취합니다. tRPC는 API를 '정의'하는 것이 아니라 '함수를 공유'하는 개념에 가깝습니다. 서버에서 정의한 프로시저(Procedure)의 타입을 클라이언트가 직접 참조하기 때문에, 런타임 오버헤드 없이 컴파일 타임에 모든 오류를 잡아낼 수 있습니다. 이는 코드 생성(Code Generation) 과정이 필요한 GraphQL과 차별화되는 지점입니다. 또한 REST와 달리 별도의 문서화 도구 없이도 코드 자체가 완벽한 명세서 역할을 수행합니다.
3. 실제 사용 사례
실무 환경에서 각 기술은 고유의 강점을 발휘하는 영역이 뚜렷합니다. REST는 공개 API(Public API)를 구축할 때 여전히 최선의 선택입니다. 전 세계의 수많은 개발자가 REST에 익숙하며, 특별한 도구 없이도 `curl`이나 브라우저만으로 테스트가 가능하기 때문입니다. 예를 들어 Stripe나 GitHub의 외부 연동 API는 호환성을 위해 REST를 고수하고 있습니다. 또한 캐싱 전략이 중요한 정적 콘텐츠 제공 서비스에서도 HTTP 표준 캐싱을 활용하기 쉬운 REST가 유리합니다.
GraphQL은 복잡한 관계형 데이터를 다루는 대규모 애플리케이션에서 빛을 발합니다. 페이스북이나 에어비앤비처럼 하나의 화면에 수십 개의 데이터 소스를 결합해야 하는 경우, GraphQL의 단일 쿼리 요청은 네트워크 왕복 횟수를 획기적으로 줄여줍니다. 특히 마이크로서비스 아키텍처(MSA)에서 여러 서비스의 데이터를 하나로 묶어주는 API 게이트웨이 역할을 수행할 때 매우 효과적입니다.
tRPC는 풀스택 TypeScript 환경, 특히 모노레포 구조의 프로젝트에서 압도적인 효율을 보여줍니다. Next.js 14/15나 Remix 환경에서 백엔드와 프런트엔드를 동시에 개발할 때, tRPC를 사용하면 서버 코드를 수정하는 즉시 클라이언트 코드에서 타입 에러가 발생하여 실수를 사전에 방지할 수 있습니다. 스타트업이나 소규모 팀이 빠른 속도로 기능을 개발하고 안정성을 유지해야 할 때 tRPC는 가장 강력한 도구가 됩니다.
4. 성능과 생태계
성능 측면에서 보면 REST와 tRPC는 상대적으로 가볍습니다. REST는 단순한 HTTP 요청 처리에 집중하며, tRPC는 내부적으로 JSON-RPC 스타일의 요청을 보내지만 복잡한 파싱 과정이 없습니다. 반면 GraphQL은 서버 측에서 클라이언트가 보낸 쿼리 문자열을 파싱하고 유효성을 검사하며, 실행 계획을 세우는 과정에서 CPU 자원을 더 많이 소모합니다. 이는 트래픽이 매우 높은 환경에서 서버 비용의 차이로 이어질 수 있습니다. 하지만 클라이언트 측 성능에서는 GraphQL이 불필요한 데이터를 걸러주어 네트워크 페이로드를 줄여주는 이점이 있습니다.
생태계의 성숙도는 REST가 가장 앞서 있으며, 그 뒤를 GraphQL이 바짝 쫓고 있습니다. REST는 거의 모든 언어와 프레임워크에서 기본적으로 지원하며, 보안 및 모니터링 도구가 풍부합니다. GraphQL은 Apollo, Relay와 같은 강력한 클라이언트 라이브러리와 데이터 캐싱 솔루션을 보유하고 있습니다. tRPC는 상대적으로 신생 기술이지만, TypeScript 커뮤니티의 폭발적인 지지를 받으며 TanStack Query(React Query)와의 완벽한 통합을 제공하는 등 빠르게 성장하고 있습니다. 특히 최근 React 19의 서버 컴포넌트와 함께 사용될 때의 시너지가 기대되고 있습니다.
5. 언제 무엇을 선택할까
결론적으로 '어떤 기술이 최고인가'에 대한 답은 프로젝트의 성격과 팀의 구성에 따라 달라집니다. 만약 당신의 팀이 다양한 언어(Java, Python, Go 등)를 사용하고 있으며, 외부 개발자들에게 API를 개방해야 한다면 REST를 선택하는 것이 가장 안전하고 합리적입니다. 표준을 따르는 것은 곧 유지보수성과 확장성을 보장하는 길이기 때문입니다.
복잡한 데이터 구조를 가지고 있고 클라이언트의 요구사항이 빈번하게 변경되는 대규모 서비스라면 GraphQL이 정답이 될 수 있습니다. 특히 프런트엔드 팀과 백엔드 팀이 분리되어 있어 서로의 의존성을 줄이고 싶을 때 GraphQL의 스키마는 훌륭한 계약서 역할을 합니다. 다만 쿼리 복잡도 관리와 성능 최적화에 추가적인 비용이 발생한다는 점을 명심해야 합니다.
마지막으로, 프로젝트 전체를 TypeScript로 작성하고 있으며 개발 속도와 타입 안전성이 최우선이라면 망설임 없이 tRPC를 추천합니다. tRPC는 스키마를 정의하고 코드를 생성하는 지루한 반복 작업을 완전히 제거해 줍니다. 특히 Vite 5.x 기반의 최신 웹 스택을 사용한다면 tRPC가 제공하는 DX(개발자 경험)는 다른 기술이 따라오기 힘든 수준입니다. 기술 선택의 핵심은 현재 직면한 문제를 가장 적은 비용으로 가장 효과적으로 해결하는 것입니다.