🔷 GraphQL9. 실전 사례01 — Meta: The Origin

01 — Meta: The Origin

한 줄 답: GraphQL은 2012년 Facebook iOS 앱의 News Feed 라운드트립 사고에서 태어났고, 지금도 Meta 내부에서 모든 mobile/web 응답의 사실상 표준이다. 외부에 공개된 것은 명세와 참조 구현뿐, 운영 노하우는 14년간 내부 자산으로 축적됐다.


Why — 왜 Meta가 출발점인가

GraphQL을 이해하려면 그것이 풀려고 만들어진 첫 문제를 봐야 한다. 그 문제는 깔끔하지 않다 — 알고리즘 논문도, 백엔드 아키텍처 토론도 아니다. 셀룰러 네트워크에서 사용자가 빈 화면을 보고 있다는 사실이었다.

흔한 오해현실
”GraphQL은 백엔드 사람들이 만들었다”모바일 클라이언트 엔지니어들이 만들었다 — Nick Schrock, Dan Schafer, Lee Byron
”Facebook 내부 graph는 GraphQL spec과 거의 같다”내부는 spec의 상위 집합이다 — extension·directive·custom scalar가 spec에 없는 것도 많다
”한 번 만든 뒤 다 끝났다”14년째 spec과 내부 구현이 따로 진화한다 — Relay, persisted query, defer/stream 같은 기능이 내부에서 검증된 뒤 외부로 나온다

Meta의 사례는 GraphQL의 가능성 공간의 상한선을 보여준다 — “이 정도까지 쓸 수 있다”는 증명.


How — 어떻게 시작됐나

1) 2012년 봄, iOS 앱의 위기

2011년까지 Facebook의 iOS 앱은 HTML5 wrapper였다 — 네이티브 셸 안에서 m.facebook.com을 띄우는 구조. 성능과 사용자 경험이 한계에 달했고, 회사는 “completely native”로 다시 만들기로 결정했다.

문제는 데이터였다. 기존 백엔드는 HTML을 돌려주는 데 최적화되어 있었고, 새 iOS 앱은 구조화된 JSON이 필요했다. 임시로 만든 REST 엔드포인트들은 News Feed 한 화면을 그리기 위해 수십 번의 라운드트립을 요구했다 — 포스트, 작성자, 댓글, 좋아요, 이미지 메타데이터가 모두 별도 호출이었다.

Lee Byron의 회고(leebyron.com, softwareatscale.dev 인터뷰 등 다수)에 따르면, 그들이 던진 질문은 *“백엔드가 그래프인데 왜 그것을 평탄화해서 보내고 클라이언트가 다시 그래프로 복원해야 하나?”*였다.

2) SuperGraph 프로토타입 (2012년 2~8월)

Nick Schrock·Dan Schafer·Lee Byron 세 명이 SuperGraph라는 이름의 프로토타입을 만들기 시작한다. 핵심 발상 셋:

#발상결과로 굳어진 GraphQL 기능
1클라이언트가 원하는 응답의 모양을 텍스트로 보낸다selection set
2백엔드 객체 그래프를 타입 시스템으로 외부에 노출한다schema / SDL의 원형
3응답은 요청과 동형이다 — 필요한 만큼만response-request isomorphism

2012년 8월, 새 iOS Facebook 앱이 출시될 때 News Feed의 첫 화면을 그리는 호출은 GraphQL 한 번이었다. 외부 발표는 3년 뒤에 한다.

3) Relay와 외부 공개 (2015)

GraphQL이 외부에 알려진 건 두 단계로 이뤄진다.

시점사건출처
2015년 1월React.js Conf에서 Relay와 GraphQL 함께 발표legacy.reactjs.org/blog/2015/02/20/introducing-relay-and-graphql.html
2015년 7월React Europe에서 spec 초안 미리보기(Lee Byron 키노트)
2015년 9월 14일spec 0.x와 graphql-js 참조 구현 공개engineering.fb.com/2015/09/14/core-infra/graphql-a-data-query-language

Relay는 Facebook이 내부에서 어떻게 쓰는지를 보여주는 단서였다 — fragment colocation, connection pagination, persisted query가 spec 자체보다 Relay 규약에 먼저 등장했다.

4) 운영 (2018~현재)

2018년 11월, Facebook은 GraphQL의 상표·도메인·저작권을 Linux Foundation 산하 GraphQL Foundation으로 이관한다. 이때 Airbnb·Apollo·GitHub·Shopify·Twitter 등이 founding member로 합류한다.

Lee Byron, “Introducing the GraphQL Foundation” (2018): “When a language outgrows its creator, that’s when it becomes a standard.”

내부 운영 규모는 외부 발표에서 단편적으로만 확인된다. 가장 자주 인용되는 수치는 engineering.fb.com 2015년 글의 *“hundreds of billions of API calls a day”*이고, 그 뒤로는 컨퍼런스 키노트에서 “수천억” 단위가 반복 언급된다 (정확한 최신 수치는 비공개).


What — 구체 사양

Meta 내부 GraphQL의 spec 대비 확장된 부분

주의 — 아래는 공개 자료(컨퍼런스 토크, 블로그, spec proposal)에서 확인 가능한 것만 정리. 내부 비공개 부분은 추측 금지.

기능spec 상태Meta 내부에서 먼저
@defer / @streamspec proposal (2023~)이미 production 운영 중
Persisted queryspec 외 생태계 관행모든 client 요청이 ID 기반
Fragment colocationRelay spec컴파일러가 강제
Type relay (Node interface)Relay Server specglobal ID 시스템
Schema-as-a-service(spec 없음)단일 거대 graph + service ownership

공개 자료에서 확인되는 내부 graph 특성

  • 단일 거대 graph: 마이크로서비스 단위로 federation하지 않고, 한 거대한 schema로 운영. Netflix·Airbnb의 federation과 정반대 선택.
  • persisted query 강제: client는 쿼리 텍스트가 아니라 컴파일 시점에 등록된 ID를 보낸다 — payload 크기 감소 + 보안.
  • 컴파일러 중심: Relay 컴파일러가 fragment 합치고 query 등록하고 타입 생성을 빌드 시점에 한다.

외부 공개 산출물 타임라인

연도산출물
2015spec 0.x draft, graphql-js, Relay Classic
2016spec October 2016 — 첫 정식 버전
2018Relay Modern, GraphQL Foundation 이관
2021spec October 2021 — 현재 안정 버전
2023~@defer/@stream working group 활성화

What-if — 잘못 이해하면

1) “Meta가 쓰는 방식 그대로 따라가야 한다”고 믿으면

→ Meta는 한 거대 graph + Relay 컴파일러로 운영한다. 이 모델은 수천 명 엔지니어 + 자체 컴파일러 팀이 있을 때 작동한다. 대응: 조직 규모가 100~500 사이라면 federation(06-federation), 100 미만이면 단일 모놀리스 graph가 더 현실적.

2) “Relay 없이 쓰면 GraphQL 반쪽이다”라고 믿으면

→ Relay는 Meta의 내부 컨벤션을 외부에 옮긴 클라이언트다. Apollo Client, urql, TanStack Query + codegen으로 가도 spec은 같다. 대응: 팀이 이미 Apollo 생태계라면 Relay로 갈아탈 이유 없음 — 모델만 빌려 와도 충분.

3) “spec에 없는 기능은 production에 쓰면 안 된다”고 믿으면

→ persisted query, @deferMeta가 먼저 쓰고 spec에 늦게 들어온 기능이 다수. 생태계 관행을 무시하면 성능·보안에서 손해. 대응: spec 외 관행도 주류 client/server에 구현되어 있으면 안전하게 채택.

4) “Meta 규모만큼 안 크면 GraphQL을 안 써도 된다”고 믿으면

→ Meta 규모가 최저 도입 조건이 아니라 최대 운영 한계다. GitHub·Shopify 사례를 보면 훨씬 작은 조직에서 GraphQL이 이긴다. 대응: 규모가 아니라 문제 모양(가변 응답·다중 클라이언트)을 기준으로 결정.


Insight — 흥미로운 이야기

”GraphQL의 GraphQL 아닌 것 — Open Graph”

이름의 ‘Graph’는 데이터베이스 의미의 그래프가 아니다. Facebook이 2010년대 초 자사 데이터 모델을 Open Graph라 부른 데서 왔다 — 사람·페이지·사건이 노드, 관계(좋아요·친구·태그)가 엣지로 연결되는 소셜 그래프. 즉 GraphQL은 그래프 DB 쿼리 언어가 아니라, 그래프 모양의 도메인을 위한 쿼리 언어다. 백엔드가 MySQL이든 TAO(Facebook의 graph cache)든 Postgres든 상관없다.

”Lee Byron이 immutable.js 같은 사람”

GraphQL 외에 Lee Byron이 만든 것 — immutable.js(Facebook의 영구 자료구조 라이브러리), TC39의 JavaScript pipeline operator(|>) proposal, GraphQL Working Group의 의장. 한 사람이 한 도구를 만들고 그 도구가 표준이 되는 과정에 14년을 쓴다는 패턴은 흔치 않다.

”처음 3년간 외부에 공개하지 않은 이유”

Lee Byron의 Postman 인터뷰(blog.postman.com/what-is-graphql-part-one-the-facebook-years)에 따르면, 공개하지 않은 게 아니라 공개할 여력이 없었다. 2012~2014년 동안 Facebook 내부에서 GraphQL은 iOS·Android·Web으로 빠르게 퍼지면서 명세가 계속 바뀌었다. “외부에 줄 수 있을 만큼 안정화하는 데 3년이 걸렸다”는 회고.

”공개의 진짜 동기는 React 생태계”

2015년 1월 Relay 발표는 GraphQL 발표가 아니라 Relay 발표였다. React가 이미 외부에 성공한 상태에서, Relay의 데이터 페칭 모델을 설명하려면 GraphQL이 필요했다. 즉 GraphQL의 외부 공개는 React의 부산물이었다는 해석이 가능하다 — 만약 React가 외부에 없었다면 GraphQL도 내부 자산으로 남았을지 모른다.


요약 + 다이어그램

Meta의 GraphQL은 iOS 모바일 News Feed의 라운드트립 문제를 풀려고 태어났고, Relay와 함께 자랐고, 2018년 Foundation으로 분리되었다. 내부는 단일 거대 graph + persisted query + 컴파일러로 운영하며, 이 모델은 spec에 역으로 영향을 준다.

참고 자료

  • Lee Byron, “Introducing the GraphQL Foundation”leebyron.com/introducing-the-graphql-foundation
  • Engineering at Meta, “GraphQL: A data query language” (2015-09-14) — engineering.fb.com/2015/09/14/core-infra/graphql-a-data-query-language
  • React Blog, “Introducing Relay and GraphQL” (2015-02-20) — legacy.reactjs.org/blog/2015/02/20/introducing-relay-and-graphql.html
  • Software at Scale 44, Building GraphQL with Lee Byronsoftwareatscale.dev/p/software-at-scale-44-building-graphql
  • Nordic APIs, Interview With GraphQL Co-Creator Lee Byronnordicapis.com/interview-with-graphql-co-creator-lee-byron
  • Postman Blog, What is GraphQL? Part 1: The Facebook Years

다음 문서: 02-github-public-api-v4.mdx — GraphQL이 처음으로 외부 개발자에게 노출된 순간.