TechFeedTechFeed
Backend

GraphQL vs REST API — 2026년 비교

한 줄 요약: GraphQL은 클라이언트가 필요한 데이터를 정확히 요청하는 구조고, REST는 서버가 정의한 엔드포인트에서 데이터를 가져온다. 2026년 기준으로 두 기술은 공존하며, 선택 기준은 팀 구성, 프로덕트 특성, 운영 역량에 달려 있다. REST와 GraphQL의 가장 근본적인 차이는 데이터 형태를 누가 결정하느냐다. REST: 서버가 결정한다.

by

한 줄 요약: GraphQL은 클라이언트가 필요한 데이터를 정확히 요청하는 구조고, REST는 서버가 정의한 엔드포인트에서 데이터를 가져온다. 2026년 기준으로 두 기술은 공존하며, 선택 기준은 팀 구성, 프로덕트 특성, 운영 역량에 달려 있다.


GraphQL이 나온 지 10년이 넘었지만 REST를 완전히 대체하지 못했다. 이유가 있다. GraphQL이 해결하는 문제가 분명하지만, 그 해결이 새로운 복잡성을 만든다. 이 글은 쿼리 유연성, 오버/언더페칭, 캐싱, 타입 시스템, 도구 생태계를 기준으로 두 접근 방식을 비교하고, 어떤 상황에서 무엇을 선택해야 하는지 판단 기준을 제시한다.


핵심 차이 — 누가 데이터 형태를 결정하는가

REST와 GraphQL의 가장 근본적인 차이는 데이터 형태를 누가 결정하느냐다.


  • REST: 서버가 결정한다. GET /users/1은 서버가 미리 정의한 User 객체를 반환한다. 클라이언트는 그 형태 전체를 받는다.
  • GraphQL: 클라이언트가 결정한다. 클라이언트가 쿼리에 필요한 필드를 명시하면 서버는 그 필드만 반환한다.

이 차이에서 모든 장단점이 파생된다.


핵심 차이 — 누가 데이터 형태를 결정하는가 — 시스템 아키텍처 다이어그램
GraphQL vs REST API — 2026년 비교 — 시스템 아키텍처 다이어그램 (출처: 공식 문서 및 벤치마크 데이터 기반)

오버페칭과 언더페칭

오버페칭(Overfetching)은 필요한 것보다 많은 데이터를 받는 것이다. 모바일 앱에서 사용자 이름만 표시하면 되는데 REST 엔드포인트가 프로필 이미지, 주소, 결제 정보까지 반환하는 경우다. 불필요한 데이터가 네트워크 대역폭을 낭비하고, 특히 저사양 모바일 환경에서 체감된다.


언더페칭(Underfetching)은 하나의 뷰를 렌더링하기 위해 여러 엔드포인트를 호출해야 하는 것이다. 게시글 목록과 각 게시글 작성자 정보를 함께 보여주려면 GET /posts 후 각 GET /users/{id}를 반복 호출해야 하는 N+1 문제가 대표적이다.


GraphQL은 이 두 문제를 동시에 해결한다. 단 하나의 쿼리로 게시글과 작성자 이름을 정확히 요청할 수 있다.


오버페칭과 언더페칭 — 처리량 벤치마크 비교
GraphQL vs REST API — 2026년 비교 — 처리량 벤치마크 비교 (출처: 공식 문서 및 벤치마크 데이터 기반)

코드 비교 — 같은 데이터를 가져오는 두 방식

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 도입의 초기 학습 비용을 높인다.


코드 비교 — 같은 데이터를 가져오는 두 방식 — 데이터 흐름도
GraphQL vs REST API — 2026년 비교 — 데이터 흐름도 (출처: 공식 문서 및 벤치마크 데이터 기반)

비교표 — REST vs GraphQL

2026년 선택 기준

GraphQL을 선택하는 상황

  • 클라이언트(모바일 앱, 여러 타입의 SPA)가 같은 백엔드에서 서로 다른 데이터 형태를 필요로 할 때
  • 프론트엔드 팀이 백엔드 의존성 없이 빠르게 데이터 요구사항을 바꿔야 할 때
  • 실시간 데이터(채팅, 알림)가 필요하고 GraphQL Subscription을 활용하고 싶을 때
  • 복잡한 도메인 모델 (소셜 그래프, 커머스 카탈로그 등)에서 중첩 관계를 단일 쿼리로 처리해야 할 때

REST를 선택하는 상황

  • 외부 개발자에게 공개하는 API일 때 — HTTP 캐싱, 단순함, 폭넓은 클라이언트 지원이 유리
  • 팀이 작고 GraphQL 생태계 학습 비용을 감당하기 어려울 때
  • 파일 업로드, 간단한 CRUD, 고정된 클라이언트 하나가 전부일 때
  • 마이크로서비스 간 내부 통신 — gRPC가 더 나은 선택일 수도 있음

실무 조언: 2026년 현재 많은 팀이 "GraphQL Federation" 또는 "BFF(Backend For Frontend)" 패턴을 채택한다. 마이크로서비스 내부는 REST로 유지하고, 클라이언트에 노출되는 레이어만 GraphQL Federated Gateway로 통합하는 방식이다. 처음부터 전체를 GraphQL로 전환하는 것보다 점진적 도입이 현실적이다.
주의: GraphQL은 "무엇이든 쿼리할 수 있다"는 유연성이 보안 취약점이 될 수 있다. Depth Limit(중첩 깊이 제한), Complexity Limit(쿼리 복잡도 제한), Rate Limiting을 반드시 설정해야 한다. 이를 설정하지 않으면 악의적인 복잡한 쿼리로 서버가 다운될 수 있다.

자주 묻는 질문

GraphQL 도입 시 가장 자주 발생하는 실수는 무엇인가요?

가장 빈번한 함정은 리졸버에서 발생하는 N+1 쿼리를 방치하는 것입니다. 게시글 목록을 받고 각 게시글의 작성자를 중첩 필드로 요청하면 작성자 수만큼 DB 쿼리가 따로 나가는데, DataLoader 패턴으로 배치 처리하지 않으면 트래픽이 늘수록 DB가 먼저 무너집니다. 두 번째는 보안 설정 누락입니다. GraphQL은 클라이언트가 쿼리 형태를 자유롭게 짜기 때문에 Depth Limit, Complexity Limit, Rate Limiting을 걸지 않으면 깊게 중첩된 악성 쿼리 한 방으로 서버가 다운될 수 있습니다. 마지막으로 POST 기반이라 HTTP 캐싱이 자동으로 동작하지 않는다는 점을 간과하고 REST처럼 CDN 캐싱을 기대하는 경우가 많습니다.


다른 대안과 비교했을 때 어떤 상황에 적합한가요?

GraphQL은 여러 종류의 클라이언트가 같은 백엔드에서 서로 다른 데이터 형태를 요구하거나, 모바일처럼 오버페칭이 체감되는 환경, 소셜 그래프·커머스 카탈로그처럼 중첩 관계를 단일 쿼리로 가져와야 하는 SPA에 적합합니다. 실시간 알림이 필요하면 Subscription이 내장된 점도 강점입니다. 반대로 외부 개발자에게 공개하는 API라면 HTTP 캐싱과 폭넓은 클라이언트 지원을 갖춘 REST가 여전히 사실상 표준이라 더 낫고, 팀이 작아 DataLoader·Depth Limit 설정 같은 학습 비용을 감당하기 어렵거나, 고정된 클라이언트 하나에 단순 CRUD와 파일 업로드만 필요한 경우에는 GraphQL이 과합니다. 마이크로서비스 내부 통신이라면 gRPC가 더 맞을 수도 있습니다.


더 깊게 공부하려면 어떤 자료를 보면 좋을까요?

기초는 GraphQL 공식 학습 문서(graphql.org/learn)로 스키마·쿼리·리졸버 개념을 잡으시고, 실제 서버·클라이언트 구현은 Apollo 공식 문서(apollographql.com/docs)가 가장 체계적입니다. 여기서 한 단계 더 들어간다면 꼭 익혀야 할 핵심 개념은 세 가지입니다. 리졸버의 N+1을 잡는 DataLoader 패턴, POST 기반 캐싱 한계를 보완하는 Persisted Queries, 그리고 악성 쿼리를 막는 Depth Limit·Complexity Limit입니다. REST 쪽 타입 안전성을 비교하고 싶다면 OpenAPI(Swagger)와 tRPC 문서를 함께 보면 두 진영의 도구 생태계가 한눈에 잡힙니다.


GraphQL vs REST API, 한 줄로 정리하면 어떻게 되나요?

차이는 데이터 형태를 누가 정하느냐 한 가지로 압축됩니다. REST는 서버가 엔드포인트별 응답 형태를 고정하고, GraphQL은 클라이언트가 필요한 필드만 쿼리로 지정합니다. 이 차이에서 GraphQL은 오버·언더페칭을 기본 해결하고 타입 스키마를 내장하는 대신 캐싱과 N+1, 보안 설정이라는 새 비용을 떠안고, REST는 HTTP 캐싱과 단순함을 가져가는 대신 N+1을 엔드포인트 설계로 직접 회피해야 합니다. 결국 둘은 우열이 아니라 팀 규모·클라이언트 다양성·운영 역량에 따라 골라 쓰거나 BFF로 함께 쓰는 관계입니다.


기존 REST 프로젝트에 GraphQL을 처음 도입할 때 무엇부터 확인해야 하나요?

전체를 한 번에 GraphQL로 갈아엎지 마시고, 캐싱 전략부터 점검하시기를 권합니다. REST에서 Cache-Control과 ETag로 잘 캐싱되던 엔드포인트가 GraphQL의 POST 요청으로 바뀌면 CDN 캐싱이 깨지므로, 이 부분은 Persisted Queries나 Apollo Client 캐시로 대체할 계획을 먼저 세워야 합니다. 현실적인 접근은 마이크로서비스 내부 통신은 REST로 유지하고, 클라이언트에 노출되는 레이어만 BFF(Backend For Frontend)나 GraphQL Federation으로 점진적으로 감싸는 방식입니다. 처음부터 전면 전환보다 손실 적은 도입 경로입니다.


GraphQLRESTAPI백엔드비교

함께 보면 좋은 문제 해결

관련 포스트