GraphQL vs REST API — 2026년 비교
쿼리 유연성, 캐싱, 타입 시스템, 도구 생태계 비교와 프로젝트별 선택 가이드.
한 줄 요약: GraphQL은 클라이언트가 필요한 데이터를 정확히 요청하는 구조고, REST는 서버가 정의한 엔드포인트에서 데이터를 가져온다. 2026년 기준으로 두 기술은 공존하며, 선택 기준은 팀 구성, 프로덕트 특성, 운영 역량에 달려 있다.
GraphQL이 나온 지 10년이 넘었지만 REST를 완전히 대체하지 못했다. 이유가 있다. GraphQL이 해결하는 문제가 분명하지만, 그 해결이 새로운 복잡성을 만든다. 이 글은 쿼리 유연성, 오버/언더페칭, 캐싱, 타입 시스템, 도구 생태계를 기준으로 두 접근 방식을 비교하고, 어떤 상황에서 무엇을 선택해야 하는지 판단 기준을 제시한다.
핵심 차이 — 누가 데이터 형태를 결정하는가
REST와 GraphQL의 가장 근본적인 차이는 데이터 형태를 누가 결정하느냐다.
- REST: 서버가 결정한다.
GET /users/1은 서버가 미리 정의한 User 객체를 반환한다. 클라이언트는 그 형태 전체를 받는다. - GraphQL: 클라이언트가 결정한다. 클라이언트가 쿼리에 필요한 필드를 명시하면 서버는 그 필드만 반환한다.
이 차이에서 모든 장단점이 파생된다.
오버페칭과 언더페칭
오버페칭(Overfetching)은 필요한 것보다 많은 데이터를 받는 것이다. 모바일 앱에서 사용자 이름만 표시하면 되는데 REST 엔드포인트가 프로필 이미지, 주소, 결제 정보까지 반환하는 경우다. 불필요한 데이터가 네트워크 대역폭을 낭비하고, 특히 저사양 모바일 환경에서 체감된다.
언더페칭(Underfetching)은 하나의 뷰를 렌더링하기 위해 여러 엔드포인트를 호출해야 하는 것이다. 게시글 목록과 각 게시글 작성자 정보를 함께 보여주려면 GET /posts 후 각 GET /users/{id}를 반복 호출해야 하는 N+1 문제가 대표적이다.
GraphQL은 이 두 문제를 동시에 해결한다. 단 하나의 쿼리로 게시글과 작성자 이름을 정확히 요청할 수 있다.
코드 비교 — 같은 데이터를 가져오는 두 방식
REST — 게시글 목록 + 작성자 이름 조회 (N+1 문제)// 1단계: 게시글 목록 조회 GET /api/posts // Response: [{ id: 1, title: '...', authorId: 42 }, ...] // 2단계: 각 게시글의 작성자 조회 (N번 호출) GET /api/users/42 // Response: { id: 42, name: 'Alice', email: '...', address: '...' } // → name만 필요하지만 전체 User 객체를 받음 (오버페칭) // 총 호출 수: 게시글 수 + 1
GraphQL — 단일 쿼리로 필요한 데이터만 조회# 단 한 번의 요청으로 필요한 데이터만 지정 query GetPostsWithAuthors { posts { id title author { name # email, address 등은 요청하지 않음 } } } # Response: # { # "data": { # "posts": [ # { "id": 1, "title": "...", "author": { "name": "Alice" } } # ] # } # } # 총 호출 수: 1
캐싱 — REST의 강점
캐싱은 REST가 GraphQL보다 구조적으로 유리한 영역이다.
REST 캐싱
REST는 HTTP 캐싱을 그대로 활용한다. GET /posts/1은 URL이 고정되어 있어 CDN이나 브라우저가 응답을 캐싱할 수 있다. Cache-Control, ETag, Last-Modified 헤더가 표준 HTTP 캐싱 메커니즘과 자연스럽게 통합된다.
GraphQL 캐싱의 어려움
대부분의 GraphQL 구현은 HTTP POST를 사용한다. POST 요청은 HTTP 표준상 기본 캐싱 대상이 아니다. 따라서 URL 기반 CDN 캐싱이 동작하지 않는다.
GraphQL은 대신 Persisted Queries(쿼리를 해시로 등록하고 GET으로 요청), Apollo Client 캐시(클라이언트 사이드 캐싱), DataLoader(배치 처리와 메모이제이션)로 캐싱 문제를 보완한다. 하지만 이 모든 것은 별도로 설정해야 한다.
공개 API의 경우
외부 개발자가 사용하는 공개 API라면 REST가 여전히 표준이다. HTTP 캐싱, 다양한 클라이언트 지원, 브라우저에서 직접 테스트 가능한 단순함이 장점이다. GitHub, Twitter/X, Stripe 등 대부분의 공개 API는 REST를 기본으로 쓴다(일부는 GraphQL을 추가로 제공).
타입 시스템과 도구 생태계
GraphQL 스키마 — 계약 명세
GraphQL의 가장 큰 장점 중 하나는 스키마가 API의 단일 진실 소스가 된다는 것이다. 스키마에서 타입, 관계, 입력/출력 형식이 모두 정의되며, 이를 기반으로 타입스크립트 타입, 문서, 클라이언트 SDK를 자동 생성할 수 있다.
- GraphQL Code Generator: 스키마에서 TypeScript 타입과 훅을 자동 생성
- GraphiQL / Apollo Sandbox: 브라우저에서 스키마를 탐색하고 쿼리를 테스트
- Apollo Studio: 스키마 변경 추적, 필드 사용량 분석
REST의 타입 시스템
REST 자체에는 타입 시스템이 없다. 하지만 OpenAPI(Swagger)로 스키마를 정의하면 유사한 수준의 타입 생성, 문서화, 모킹이 가능하다. tRPC는 별도 스키마 없이 TypeScript 타입만으로 REST와 유사한 엔드포인트를 타입 안전하게 만든다.
N+1 문제 — DataLoader
GraphQL 서버에서는 리졸버가 중첩 타입을 처리하다 보면 N+1 쿼리가 발생하기 쉽다. DataLoader 패턴으로 배치 처리하면 해결된다. 단, DataLoader 설정은 개발자가 직접 해야 하며, 이 부분이 GraphQL 도입의 초기 학습 비용을 높인다.
비교표 — REST vs GraphQL
2026년 선택 기준
GraphQL을 선택하는 상황
- 클라이언트(모바일 앱, 여러 타입의 SPA)가 같은 백엔드에서 서로 다른 데이터 형태를 필요로 할 때
- 프론트엔드 팀이 백엔드 의존성 없이 빠르게 데이터 요구사항을 바꿔야 할 때
- 실시간 데이터(채팅, 알림)가 필요하고 GraphQL Subscription을 활용하고 싶을 때
- 복잡한 도메인 모델 (소셜 그래프, 커머스 카탈로그 등)에서 중첩 관계를 단일 쿼리로 처리해야 할 때
REST를 선택하는 상황
- 외부 개발자에게 공개하는 API일 때 — HTTP 캐싱, 단순함, 폭넓은 클라이언트 지원이 유리
- 팀이 작고 GraphQL 생태계 학습 비용을 감당하기 어려울 때
- 파일 업로드, 간단한 CRUD, 고정된 클라이언트 하나가 전부일 때
- 마이크로서비스 간 내부 통신 — gRPC가 더 나은 선택일 수도 있음