🔷 GraphQL8. 이론 & 대안07 — When NOT to Use GraphQL

07 — When NOT to Use GraphQL

한 줄 답: GraphQL은 만능 도구가 아니다. (a) 단순 CRUD, (b) 큰 파일 streaming, (c) 강한 HTTP 캐시 의존, (d) 팀이 GraphQL 운영 경험 0, (e) 클라이언트가 모두 자기 팀이고 1:1 BFF로 충분한 경우 — 이 중 하나라도 강하게 해당하면 REST or RPC가 더 낫다. 도입 비용은 학습·운영·관측·보안 네 갈래로 모두 든다.


Why — 왜 이 문서가 필요한가

GraphQL 도입 회의에서 가장 자주 빠지는 것이 “안 쓰는 게 나은 경우”의 검토다. GraphQL 진영의 책·블로그·컨퍼런스 자료는 대부분 도입의 장점만 다룬다. 그래서 6개월~1년 운영해 본 팀들 사이에서 *“우리 케이스에 GraphQL이 안 맞았다”*는 회고가 자주 나온다 — Coinbase, Wayfair, Medium 등의 공개 회고가 이 갈래에 속한다.

이 문서는 그 회고들을 5가지 패턴으로 정리한다. 도입 전에 한 번 검토하고, 해당하면 GraphQL을 피하는 것이 더 나은 선택임을 인정하는 것이 목적.


How — 5가지 부적합 패턴

패턴 (a) — 단순 CRUD

가장 흔한 부적합 케이스.

GET    /users/:id
POST   /users
PUT    /users/:id
DELETE /users/:id

이 모양이 그 자체로 모델이라면, GraphQL을 얹는 것은 overhead만 추가다.

비교RESTGraphQL
한 화면 → 한 호출YESYES
응답 모양 변동NO (고정 User)YES (그러나 필요 없음)
관계 traversalNO (필요 없음)YES (그러나 필요 없음)
codegenOpenAPI 한 줄schema + tooling + Apollo
학습 곡선누구나learning curve 있음
캐시HTTP cache OK어려움

결론: 화면이 고정 모양 단일 리소스만 다루면 REST가 압도적으로 단순하다.

판단 기준:

  • 클라이언트가 한 종류이고
  • 화면이 리소스 1대1 매핑 (예: 상품 상세, 사용자 프로필)
  • 관계 traversal이 거의 없음

→ 이 셋이 다 맞으면 REST.

패턴 (b) — 큰 파일 streaming

시도: { uploadVideo(file: "...base64...") { url } }
       ↑ 50MB → JSON 안에 base64로 → 약 67MB

GraphQL은 JSON 본문이라 binary에 약하다. multipart spec(graphql-multipart-request-spec)이 있지만 복잡하고 모든 클라이언트가 지원하지 않는다.

시나리오적합
영상 업로드/다운로드REST (multipart, range request)
큰 이미지 처리REST + CDN
WebRTC streamingWebRTC (별도)
실시간 binary feedgRPC bidirectional or WebSocket
메타데이터만GraphQL OK (binary는 URL 반환)

결론: binary는 별도 endpoint. GraphQL은 그 URL의 metadata만 다룸.

실패 사례:

  • 한 이커머스 회사가 상품 이미지를 GraphQL uploadImage mutation으로 받았다가, 대용량 트래픽에서 메모리 폭발. 6개월 뒤 S3 presigned URL + REST로 전환.

패턴 (c) — 강한 HTTP 캐시 필요

GET /products/123
Cache-Control: public, max-age=300
ETag: "abc"

REST의 가장 큰 무기 — CDN과 브라우저 캐시가 그대로 동작.

GraphQL은:

  • POST가 default → 브라우저 캐시 안 됨
  • body가 매번 다름 → CDN 캐시 어려움
  • 응답이 매번 다른 모양 → normalize 캐시 필요 (Apollo Client cache)
캐시 종류RESTGraphQL
브라우저 HTTP cache자동없음
CDN edge cache자동persisted query + GET 필요
reverse proxy cache자동어려움
응용 레벨 cache별도normalized cache (Apollo·urql)

→ persisted query + GET으로 GraphQL을 CDN cacheable하게 만들 수 있긴 하지만 추가 복잡도. 이 모든 게 공짜로 오는 REST와 비교하면 명백히 불리하다.

판단 기준:

  • 응답이 대부분 정적 (상품 카탈로그, 공개 콘텐츠)
  • 트래픽이 매우 큼 (CDN이 critical)
  • 동일 응답을 수만 명에게 전달

→ 이 셋이 맞으면 REST.

패턴 (d) — 팀이 GraphQL 운영 경험 0

이게 가장 자주 무시되는 패턴이다.

GraphQL을 처음 production에 올리는 팀이 만나는 함정들:

각 함정은 production 사고로 직결된다. REST는 함정이 더 적다 — 산업이 20년의 운영 노하우를 축적한 도구.

판단 기준:

  • 팀에 GraphQL을 production에 운영해 본 사람이 없고
  • 코칭/멘토링 받을 외부 자원도 없고
  • 학습 6개월을 감내할 수 없는 일정

→ 이 셋이 맞으면 REST.

패턴 (e) — 클라이언트가 모두 자기 팀, 1:1 BFF 가능

GraphQL의 가치 제안은 N 클라이언트가 N 모양을 원할 때 극대화된다. 만약:

  • 클라이언트가 하나뿐 (예: 웹 + 모바일이 거의 같은 모양)
  • 클라이언트 팀과 백엔드 팀이 같음 — 즉시 협의 가능
  • 전통 BFF (REST) 한 개로 충분히 적응

→ GraphQL의 유연성과한 비용이 된다.

TS 모노레포 풀스택이라면 → tRPC가 더 가벼움 (04 참고) 비-TS 풀스택이라면 → REST가 가장 단순.


What — 실제 회고 사례

Coinbase의 회고 (2020)

  • 도입: 2016년 GraphQL 적극 도입
  • 회고: “public API에는 REST를 유지했다
  • 이유: 외부 개발자가 REST에 익숙했고, GraphQL learning curve가 적용률을 떨어뜨림
  • 결론: 외부 API는 REST, 내부 BFF는 GraphQL

Wayfair의 회고

  • 도입: 마이크로서비스 통합용 GraphQL Federation
  • 회고: 일부 시나리오에서 오버스펙
  • 결론: 단순 service-to-servicegRPC가 더 적합. Federation은 클라이언트 통합 layer에만.

Medium의 회고

  • 도입: 2018년 GraphQL 적용
  • 회고: 팀의 GraphQL 운영 경험 부족으로 N+1, 복잡도 폭주
  • 결론: DataLoader · persisted query · field auth처음부터 필요했음. 운영 경험이 없는 팀이라면 REST가 안전.

Netflix Falcor → GraphQL

  • Falcor를 만들고 4년 사용 → GraphQL로 전환
  • 이유: *생태계 (codegen·tooling·교육 자료)*가 GraphQL이 압도적
  • 교훈: 기술적 우수성생태계 채택은 다르다. 맞는 도구를 골랐어도 생태계가 약하면 진다.

한국 — 우아한형제들

  • 배민 광고 시스템에 GraphQL 도입
  • 회고: 광고 도메인의 가변 모양에 잘 맞았음. 결제 도메인에는 REST를 유지. 도메인별 적합도 분리.

What-if — 부적합 패턴인데도 GraphQL을 강행하면

1) 단순 CRUD인데 GraphQL 도입

학습 곡선에 1~3개월. codegen 파이프라인 운영 부담. 팀의 시간이 비즈니스가 아닌 도구 운영으로 빠짐. 대응: REST + OpenAPI로 시작, 화면이 진짜로 가변해질 때 GraphQL 추가.

2) 큰 파일을 GraphQL로 받음

→ JSON base64로 부피 30~50% 증가. multipart spec 복잡. 대용량 트래픽에서 메모리 폭발. 대응: binary는 항상 별도 endpoint. GraphQL은 metadata만.

3) HTTP 캐시 의존인데 GraphQL

→ CDN 캐시 무용. 트래픽 비용 폭증. 응답 지연 증가. 대응: persisted query + GET을 처음부터 도입. 또는 그 영역은 REST로 유지.

4) GraphQL 경험 없는 팀에 도입

→ N+1로 DB 폭주. depth 제한 없는 쿼리로 DoS 취약. field-level 인가 누락으로 데이터 노출. 대응: 외부 컨설팅 or 안 함. 보안 사고 한 번이 도입 비용보다 크다.

5) 1:1 BFF로 충분한데 GraphQL

→ overhead만 큼. 클라이언트가 더 빨라지지도 않음. 대응: 진짜로 N개 클라이언트가 생길 때까지 REST.


Insight — 흥미로운 이야기

”Hype Curve의 함정”

Gartner Hype Cycle은 모든 기술이 Peak of Inflated Expectations → Trough of Disillusionment를 거친다고 말한다. GraphQL은 2015~2019년에 최고점을 찍었다. 2020년 이후 환멸의 골짜기를 지나 생산성의 고원에 자리 잡는 중이다.

환멸의 골짜기에서 나온 회고들이 이 챕터의 자료다 — 적합한 자리·부적합한 자리가 산업 합의로 정리된 시점. 2026년 시점에서 GraphQL을 도입한다면 그 합의를 무시하지 않는 것이 옳다.

”Apollo의 마케팅 전환”

Apollo는 2018년경 *“Replace REST with GraphQL”*을 강하게 밀었지만, 2023년 이후 공식 자료는 *“GraphQL은 graph layer, REST는 resource layer — 함께 살 수 있다”*로 톤이 바뀌었다. 시장이 가르친 교훈을 가장 큰 GraphQL 회사가 인정한 것.

”GitHub의 5년”

GitHub는 2017년 GraphQL v4를 공개하며 “REST 대체”를 목표로 했다. 5년 뒤 (2022), 그들의 공식 입장은 “REST와 GraphQL은 상호 보완이다”. 일부 기능(repository graph traversal)은 GraphQL이 압도적으로 낫고, 다른 기능(file content, raw blob)은 REST가 압도적으로 낫다. 한 회사의 모든 API를 한 도구로 통일하지 못한다는 결론.

”한국의 도입 패턴”

한국 IT 회사들은 2018~2022년에 GraphQL을 적극 검토했고, 2023년 이후 선별 도입으로 정리됐다. 카카오·네이버·우아한형제들 등은 광고·콘텐츠 피드 같은 가변 영역에 GraphQL을 쓰고, 결제·로그인·정산REST/gRPC 유지. 도메인별 적합도 분리가 국내 합의에 가깝다.


요약 + 다이어그램

GraphQL은 만능이 아니다. 단순 CRUD · 큰 파일 · 강한 HTTP 캐시 · 운영 경험 0 · 1:1 BFF — 이 중 하나라도 강하게 해당하면 REST/RPC가 더 낫다. 도입 결정은 기능 매력이 아니라 5가지 안티-패턴 체크를 통과한 뒤 내려야 한다.

다음 챕터: 09-real-world-cases — 이 매트릭스를 실제 회사들은 어떻게 적용했나?