핵심 인사이트 (3줄 요약)
- 본질: GraphQL은 페이스북(Meta)이 개발한 API 쿼리 언어로, 서버가 정해준 형태의 데이터만 받아야 했던 REST와 달리 클라이언트가 주도적으로 필요한 필드와 계층 구조를 명시하여 요청하는 기술이다.
- 가치: 단일 엔드포인트(
/graphql)만으로 통신하므로, 불필요한 데이터까지 받아오는 오버패칭(Over-fetching)과 여러 API를 연속해서 찔러야 하는 언더패칭(Under-fetching)의 네트워크 지연(RTT) 낭비를 근본적으로 제거한다.- 융합: 프론트엔드의 상태 관리 라이브러리(Apollo, Relay)와 결합하여 혁신적인 개발 생산성을 제공하지만, 백엔드 로직의 복잡도 증가, HTTP 캐싱의 어려움, 그리고 N+1 쿼리 문제(Data Loader로 해결)라는 새로운 성능 트레이드오프를 낳는다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
-
개념: GraphQL(Graph Query Language)은 클라이언트 프로그램(웹, 모바일 앱 등)이 웹 서버로부터 데이터를 효율적으로 가져오기 위해 설계된 API 쿼리 언어(Query Language)이자, 그 쿼리를 파싱하고 실행하는 서버 사이드 런타임 기술이다.
-
필요성: 2012년 페이스북이 모바일 앱을 전면 재개발할 때 심각한 병목을 마주했다. 사용자의 뉴스피드를 한 화면에 그리려면 유저 정보(API 1), 게시글 목록(API 2), 각 게시글의 댓글들(API 3), 좋아요 개수(API 4)를 얻기 위해 서버를 네댓 번 연속해서 찔러야 했다(네트워크 지연 폭발). 반대로 유저 이름만 필요한데 API가 유저의 주소, 생일, 폰번호까지 1MB짜리 JSON을 통째로 쏟아내어 모바일 데이터 대역폭을 잡아먹었다. "서버가 주는 대로 받는" 기존 REST API의 군림에서 벗어나, "앱(클라이언트)이 딱 필요한 만큼만 콕 집어서 조립해달라고 주문하는" 혁신적인 쿼리 엔진이 절실했다.
-
💡 비유: REST API는 식당의 "정해진 세트 메뉴"입니다. 햄버거 세트를 시키면 내가 안 먹는 피클이나 토마토(불필요한 데이터)도 무조건 받아야 하고, 치즈스틱을 먹으려면 다른 세트를 한 번 더 주문(추가 API 호출)해야 합니다. 반면 GraphQL은 서브웨이 샌드위치나 "마라탕 주문서"와 같습니다. 종이 1장에 "빵은 얇게, 고기는 두 장, 피클은 빼고, 소스는 매운맛"이라고 내가 원하는 완벽한 형태를 펜으로 체크해서 내밀면, 주방장이 딱 그 모양의 샌드위치(JSON 데이터) 하나만 만들어서 가져다줍니다.
-
등장 배경:
- REST의 언더패칭(Under-fetching): 하나의 화면을 렌더링하기 위해 계층적으로 연관된 여러 개의 REST URL을 순차적으로 여러 번 호출해야 하는 N번의 왕복 지연(RTT) 문제.
- REST의 오버패칭(Over-fetching): 모바일 3G 환경에서 10KB면 충분한 화면에 1MB의 거대한 범용 JSON 객체를 던져주는 대역폭 낭비 사태.
- 페이스북(Meta)의 오픈소스화: 2015년 페이스북이 내부적으로 쓰던 이 괴물 쿼리 엔진을 오픈소스화하며, 프론트엔드 생태계(React)의 폭발적 성장과 함께 모던 웹 아키텍처의 쌍두마차로 올라섰다.
┌─────────────────────────────────────────────────────────────┐
│ REST API vs GraphQL 통신 구조 비교 │
├─────────────────────────────────────────────────────────────┤
│ │
│ [ REST API 방식 - Under & Over Fetching의 지옥 ] │
│ │
│ 클라이언트 ──(1. GET /users/1)─────────▶ 서버 (응답: 거대한 유저 정보)│
│ │
│ 클라이언트 ──(2. GET /users/1/posts)───▶ 서버 (응답: 수백개 글 목록)│
│ │
│ 클라이언트 ──(3. GET /posts/5/comments)▶ 서버 (응답: 댓글 정보) │
│ │
│ ⚠️ 단점: 화면 하나 그리는데 RTT 3번 소요. 쓰지도 않을 주소/나이 정보 낭비.│
│ │
│ [ GraphQL 방식 - One Endpoint, Perfect Shape ] │
│ │
│ 클라이언트 ──( POST /graphql )─────────▶ 서버 (단일 엔드포인트) │
│ [Query] │
│ query { │
│ user(id: 1) { ◀─ "유저 1번 찾아서" │
│ name ◀─ "이름만 가져오고" │
│ posts(last: 1) { ◀─ "가장 최근 게시글 1개에서" │
│ title ◀─ "제목 뽑고" │
│ comments { text } ◀─ "거기 달린 댓글 텍스트만 묶어줘" │
│ } │
│ } │
│ } │
│ │
│ 서버 (응답: 100% 클라이언트가 요구한 구조와 필드명과 똑같은 모양의 JSON 반환) │
│ 🌟 장점: 1 RTT 만에 해결. 1바이트의 오버패칭 데이터 낭비도 없음. │
└─────────────────────────────────────────────────────────────┘
[다이어그램 해설] 상단의 REST 방식은 철저하게 서버가 정의한 리소스 계층(/users, /posts, /comments)에 종속되어 있다. 관계를 맺는 데이터를 가져오기 위해 클라이언트가 발품을 팔아 여러 번 호출해야 한다. 하단의 GraphQL 구조는 이 패러다임을 역전시킨다. 통로(Endpoint)는 /graphql 단 하나뿐이다. 클라이언트가 JSON과 비슷하게 생긴 쿼리문을 작성해 POST Body에 담아 쏘면, 서버의 GraphQL 엔진(Resolver)이 백엔드의 DB나 여러 마이크로서비스를 대신 돌아다니며 데이터를 싹 긁어모아 클라이언트가 지시한 모양의 블록 트리(Graph)로 예쁘게 재조립하여 단 한방에 반환한다.
- 📢 섹션 요약 비유: REST가 매번 다른 부서에 전화해서 서류를 떼어오는 수동 결재 시스템이라면, GraphQL은 똑똑한 비서 한 명에게 "김 부장 이름, 박 과장 최근 기획서, 이 대리 회의록만 묶어서 한 장으로 뽑아와"라고 던지면 1초 만에 깔끔한 보고서를 대령하는 비서 시스템입니다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
구성 요소 (GraphQL 아키텍처)
| 요소명 | 역할 | 특성 및 내부 로직 | 비유 |
|---|---|---|---|
| Schema (스키마) | API가 제공할 데이터 구조와 타입들의 청사진 (SDL 기반) | 강타입(Strongly-typed) 언어. 프론트/백엔드의 절대적 계약서 | 식당의 재료 원산지/메뉴 규격표 |
| Query (쿼리) | 데이터(조회)를 읽어올 때 사용하는 요청 타입 (REST의 GET) | 여러 데이터를 병렬적/계층적으로 중첩 요청 가능 | "스테이크, 굽기는 레어" 주문서 |
| Mutation (뮤테이션) | 데이터를 쓰기/수정/삭제할 때 사용하는 요청 타입 (POST, PUT, DELETE) | 상태를 변화시킨 후 변경된 결과값을 즉시 리턴받을 수 있음 | "계좌 10만원 출금 후 잔고 알려줘" |
| Resolver (리졸버) | 스키마에 정의된 필드에 실제 데이터(DB 등)를 매핑하는 백엔드 함수 | 필드(Field) 단위로 독립적으로 실행되며, 연쇄(Chain) 호출됨 | 주방의 요리사들 (각자 채소, 고기 담당) |
| Introspection (인트로스펙션) | 서버 스키마 전체를 스스로 설명(문서화)하는 내부 명세 기능 | 클라이언트(GraphiQL 툴 등)가 API 스펙을 실시간으로 다운받아 자동완성 렌더링 | 자판기의 자동 메뉴 스캔 기능 |
GraphQL 백엔드의 심장: 리졸버(Resolver) 트리와 데이터 조립
클라이언트가 거대한 그래프 쿼리를 날렸을 때, 백엔드에서는 하나의 무식한 SQL 조인 쿼리가 도는 것이 아니다. GraphQL 서버는 각 노드(필드)마다 배정된 리졸버(Resolver) 함수들을 재귀적으로 호출하여 데이터를 조립한다.
┌─────────────────────────────────────────────────────────────────┐
│ Resolver(리졸버) 실행 트리와 데이터 조립 구조 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [클라이언트 요청 쿼리] │
│ query { │
│ author(id: "A") { │
│ name │
│ posts { title } │
│ } │
│ } │
│ │
│ [백엔드 Resolver 실행 트리 전개] │
│ │
│ 1. Query.author(id="A") 실행 ───▶ DB: SELECT * FROM User │
│ 결과: { id: "A", name: "Kim" } 객체 리턴 │
│ │ │
│ ├─ 2. User.name 실행 ──▶ 객체에서 "Kim" 필드 쏙 빼냄 │
│ │ │
│ └─ 3. User.posts 실행 ──▶ 부모 객체 정보(id: "A")를 넘겨받음│
│ DB: SELECT * FROM Post │
│ WHERE author_id = "A" │
│ 결과: [{title: "Hello"}] │
│ │
│ [최종 JSON 병합 결과 리턴] │
│ { │
│ "data": { │
│ "author": { │
│ "name": "Kim", │
│ "posts": [ { "title": "Hello" } ] │
│ } │
│ } │
│ } │
└─────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 클라이언트가 중첩된 쿼리를 날리면 서버의 GraphQL 엔진은 이를 트리 구조로 파싱한다. 가장 상위의 부모 리졸버(Query.author)가 먼저 실행되어 DB에서 유저 정보를 가져온다. 그리고 그 결과를 자식 리졸버(User.name, User.posts)들에게 컨텍스트 파라미터로 넘겨준다. User.posts 리졸버는 부모의 PK(author_id)를 들고 다시 DB나 다른 마이크로서비스(API)를 찔러 게시글 목록을 가져온다. 이 구조 덕분에 프론트엔드 개발자가 아무리 깊고 복잡한 트리를 요구하더라도, 백엔드 개발자는 각 필드에 대응하는 작은 리졸버 함수 조각들만 개별적으로 엮어놓으면 엔진이 알아서 레고 블록처럼 완성품을 조립해내는 혁명적 분업화가 완성된다.
- 📢 섹션 요약 비유: 종합병원에서 환자(클라이언트)가 의사 한 명(엔드포인트)에게 진료 카드를 주면, 의사가 알아서 내과, 외과, 치과(리졸버)에 연락해 결과를 싹 모아서 하나의 종합 소견서(JSON)로 깔끔하게 묶어 건네주는 시스템입니다.
Ⅲ. 융합 비교 및 다각도 분석
비교 1: GraphQL의 영원한 딜레마 - N+1 문제 (Data Loader)
프론트엔드에 무한한 자유를 주었지만 백엔드에는 끔찍한 N+1 쿼리 병목이라는 재앙이 떨어졌다.
상황: 클라이언트가 "최근 글 10개와, 각 글을 쓴 작성자의 이름"을 쿼리했다.
Query.posts리졸버가 실행되어 DB에서 글 10개를 1번의 SQL로 긁어온다. (조회 1번)- 하위 리졸버인
Post.author가 10개의 글 각각에 대해 개별적으로 10번 연속 실행되며 DB를 10번 두드린다. (조회 N번) 결과적으로 글 10개를 가져오는데 DB 쿼리가 11번(1 + 10) 나가는 최악의 성능 오버헤드가 발생한다.
해결책 (Data Loader):
Facebook이 제공하는 DataLoader 라이브러리가 표준 해결책이다. 10개의 하위 리졸버가 DB를 찌르기 위해 날아올 때, 이를 바로 DB로 보내지 않고 수 밀리초(ms) 동안 이벤트 루프 큐에 모아둔다(Batching). 그리고 모인 10개의 작성자 ID를 SELECT * FROM User WHERE id IN (1, 2, ... 10) 이라는 단 한 번의 커다란 쿼리로 묶어 DB에 던진다. 11번 나갈 쿼리를 딱 2번으로 박살 내는 백엔드 아키텍처 필수 설계 패턴이다.
비교 2: REST vs GraphQL 아키텍처의 한계와 트레이드오프
| 항목 | REST API | GraphQL | 아키텍처 선택의 기로 |
|---|---|---|---|
| HTTP 캐싱 활용 | 우수. 각 URL마다 GET으로 고유 식별되므로 CDN/브라우저 캐시 완벽 제어 (ETag, max-age) | 치명적 한계. 모든 요청이 /graphql 하나로 POST 전송되므로 HTTP/CDN 레벨의 통째 캐시 불가능 | 정적 데이터가 많은가? 동적 조회 중심인가? |
| 파일 업로드 | multipart/form-data 네이티브 지원 (단순) | 스펙상 네이티브 지원 부족. Base64 인코딩이나 별도 Multipart 스펙 억지 연동 필요 (복잡) | 파일 I/O 비중이 큰 서비스인가? |
| 상태 코드 (에러) | HTTP 404, 401, 500 코드를 정석대로 활용 | 실패해도 무조건 200 OK로 응답하고, JSON 바디 안쪽에 errors 배열을 담아 리턴 (디버깅 지옥) | 인프라 벤더(L7 로드밸런서)의 에러 모니터링 가능성 |
| 악의적 쿼리 차단 | URL 1개당 부하가 예측됨 (차단 용이) | 해커가 끝없이 중첩되는 무한 뎁스 쿼리를 보내면 서버 CPU와 DB가 즉시 터짐 (Query Complexity 관리 필수) | 퍼블릭 오픈 API로 열어둘 것인가? |
- 📢 섹션 요약 비유: 자유도가 높은 레고 장난감(GraphQL)은 아이들(프론트엔드)이 마음대로 성을 짓기엔 최고지만, 완성된 성을 통째로 코팅(캐싱)하거나 너무 거대하게 지어 무너지는 것(DB N+1 병목)을 막으려면 어른들(백엔드)의 빡센 감시와 통제가 필요합니다.
Ⅳ. 실무 적용 및 기술사적 판단
실무 시나리오
-
시나리오 — 대형 MSA 환경에서의 BFF (Backend For Frontend) 아키텍처 도입: 우버, 에어비앤비 같은 거대 플랫폼에서 모바일 앱(iOS/Android)과 웹 프론트엔드가 요구하는 데이터 화면이 제각각이다. 앱 개발자가 백엔드 팀에게 "이번에 UI가 바뀌어서 주소 필드는 빼고, 할인율 필드 새로 추가한 전용 API 하나 더 뚫어주세요"라고 매주 조르다가 개발 속도가 멈췄다.
- 판단: 백엔드 마이크로서비스들(유저, 결제, 배송 서버) 앞단에 얇은 GraphQL BFF(Backend For Frontend) 게이트웨이 레이어를 세운다. 모바일 앱 개발자는 백엔드 팀을 거치지 않고 스스로 GraphQL 쿼리를 요리조리 수정해 원하는 데이터를 찍어낸다. GraphQL 서버가 뒤쪽의 마이크로서비스 REST API 여러 개를 비동기 병렬로 대신 호출해(Orchestration) 합쳐주므로, 조직 간 커뮤니케이션 핑퐁 병목이 100% 사라지고 개발 속도가 로켓처럼 솟구친다.
-
시나리오 — 악의적인 깊이 제한(Depth Limit) 미설정으로 인한 서버 OOM 장애: 퍼블릭 서비스로 GraphQL API를 열어두었는데, 해커가
user -> posts -> author -> posts -> author형태로 깊이가 100단계 중첩된 재귀(Recursive) 쿼리를 날렸다. 백엔드 리졸버가 이를 파싱하다가 DB 커넥션을 다 물어버리고 메모리 터짐(OOM)으로 전체 서버가 마비되었다.- 판단: GraphQL 환경에서는 서버를 보호하기 위한 방패가 핵심이다. 쿼리의 **최대 중첩 깊이(Max Depth)**를 5~7 정도로 엄격하게 제한하고, 각 필드별 연산 비용을 계산하여 쿼리 1개가 차지할 수 있는 쿼리 복잡도(Query Complexity) 상한선을 설정해 악의적인 요격 쿼리를 서버 입구에서 쳐내야 한다.
┌─────────────────────────────────────────────────────────────┐
│ 실무 아키텍처: Apollo Client의 로컬 정규화 캐시 마법 │
├─────────────────────────────────────────────────────────────┤
│ │
│ [HTTP 캐시(CDN)의 한계를 극복하는 프론트엔드 전역 캐시] │
│ │
│ GraphQL 쿼리 요청 ➔ 응답 JSON 도착 │
│ { │
│ "author": { "__typename": "User", "id": 1, "name": "A" }, │
│ "post": { "__typename": "Post", "id": 9, "title": "B" } │
│ } │
│ │
│ [Apollo Client의 In-Memory Cache (정규화 스토어) 저장 로직] │
│ │
│ 캐시 저장소: │
│ - "User:1" ➔ { id: 1, name: "A" } │
│ - "Post:9" ➔ { id: 9, title: "B" } │
│ │
│ 🌟 실무 효과: │
│ 이후 프론트엔드 앱 다른 화면에서 "User:1"의 이름을 달라는 쿼리가 │
│ 발생하면, Apollo 라이브러리가 서버로 네트워크를 안 쏘고, 자신의 메모리│
│ 저장소에서 블록을 꺼내 0ms 만에 즉시 렌더링을 끝내버림! (UX 극대화) │
└─────────────────────────────────────────────────────────────┘
[다이어그램 해설] GraphQL은 태생적으로 무식하게 POST로 한 개의 URL(/graphql)만 찌르기 때문에, Nginx나 브라우저 단의 네트워크 HTTP 캐시(ETag, max-age 등)를 전혀 쓰지 못한다. 이를 극복하기 위해 실무에서는 Apollo Client나 Relay 같은 프론트엔드 라이브러리의 강력한 캐싱 아키텍처를 의존한다. 이들은 서버에서 날아온 JSON 객체들을 해체하여 [__typename]:[id]라는 고유 키로 분해해 프론트엔드의 램(RAM)에 정규화(Normalization)하여 깔아둔다. 마치 화면 단위의 캐싱이 아니라 레고 블록 단위의 캐싱이 일어나므로, 한 화면에서 갱신된 유저 이름이 페이지를 이동해도 즉각 반영되는 렌더링 최적화의 극치를 선사한다.
도입 체크리스트
- 기술적: RDB 매핑 시 발생하는 끔찍한 N+1 성능 병목을 박살내기 위해 백엔드 전역에
Data Loader(배칭 & 캐싱) 패턴이 철저하게 도입되어 있는가? - 운영·보안적: 인트로스펙션(Introspection) 기능이 상용 프로덕션(Production) 환경에서는 비활성화되어 있는가? (열려 있으면 해커가 단 클릭 1번으로 서비스의 전체 DB 구조와 API 명세서를 통째로 복제해 갈 수 있는 거대한 취약점이다).
안티패턴
-
단일 거대 리졸버 작성: 하나의 무식한 쿼리에 대해 최상단 부모 리졸버 한 곳에서 거대한 SQL JOIN 쿼리를 짜서 모든 필드 결과를 한방에 끼워 맞추어 리턴하는 행위. 이러면 "요청한 필드만 잘게 쪼개어 가볍게 조립한다"는 GraphQL의 위대한 장점과 재사용성을 스스로 차버리고 다시 끔찍한 강결합 레거시 늪으로 빠지게 된다. 리졸버는 철저하게 작게, 필드 단위로 분해해야 한다.
-
📢 섹션 요약 비유: GraphQL은 무한한 자유를 주는 마법 지팡이지만, 쓸 줄 모르는 사람(N+1 방치)이 쓰면 뒤에서 몰래 마력이 줄줄 새어나가서 서버를 쓰러뜨립니다. 반드시
Data Loader라는 마력 조절 장치(안전핀)를 끼우고 휘둘러야 합니다.
Ⅴ. 기대효과 및 결론
정량/정성 기대효과
| 구분 | REST API (서버 주도) | GraphQL (클라이언트 주도) | 개선 효과 |
|---|---|---|---|
| 정량 | 오버패칭으로 불필요한 메가바이트 낭비 | 선언한 킬로바이트 필드만 수신 | 모바일 네트워크 대역폭 페이로드 70~90% 절감 |
| 정량 | 언더패칭으로 직렬 3~4 RTT 발생 | 단일 쿼리로 그래프 조인 1 RTT | 복잡한 릴레이션 화면의 TTFB 레이턴시 3배 단축 |
| 정성 | UI 변경 시마다 백엔드 개발자 의존 | 프론트엔드가 쿼리 직접 수정 조립 | 조직 간 커뮤니케이션 핑퐁 제거, 생산성 폭발 |
미래 전망
- GraphQL과 REST의 생태계 분할 (CQRS 관점): GraphQL은 '데이터를 복잡하게 엮어서 읽어가는(Query/Read)' 화면에서 혁명적인 UX를 선사하지만, '파일 업로드나 단순 상태 변경(Mutation/Command)' 영역에서는 여전히 REST가 압도적으로 효율적이다. 따라서 한 회사가 100% GraphQL만 쓴다기보다는 조회 레이어(BFF)는 GraphQL로, 코어 백엔드 수정 로직은 REST/gRPC로 분리하는 CQRS 패턴 진화가 글로벌 표준으로 굳어지고 있다.
- 엣지 및 클라우드 연동 자동화 (Hasura, AppSync): 백엔드 개발자가 리졸버 코드를 하나하나 짜는 시대도 저물고 있다.
Hasura나AWS AppSync같은 인프라 솔루션들은, 개발자가 릴레이션 DB(PostgreSQL)의 스키마만 훅 던져주면 알아서 완벽하게 최적화된 N+1 방어 기반의 GraphQL 서버 전체를 버튼 한 번에 자동으로 찍어내는 서버리스 마법을 선보이고 있다.
참고 표준
- GraphQL Specification: 메타(Meta)가 창안하고 GraphQL Foundation이 관리하는 오픈소스 스펙
- Apollo / Relay: GraphQL 클라이언트 및 서버 생태계를 주도하는 글로벌 사실상(De facto) 라이브러리 표준
"클라이언트에게 데이터의 요청 형태를 결정할 권한을 완전히 위임하라." GraphQL이 던진 이 패러다임 전환은 20년간 이어져 온 웹 아키텍처의 권력 구조를 백엔드에서 프론트엔드로 뒤집어버렸다. 강력한 스키마 타입 기반의 안정성, 단일 엔드포인트의 통일감, 그리고 자유자재로 그래프를 조립하는 쾌감은 모바일 중심의 데이터 집약적 서비스에서 거부할 수 없는 달콤함이다. 단, 그 자유의 대가로 짊어져야 할 서버 측 최적화(Data Loader, 쿼리 캐싱 복잡도)의 십자가 무게를 이해하는 아키텍트만이 이 괴물 엔진을 제대로 다룰 수 있다.
- 📢 섹션 요약 비유: REST가 잘 차려진 코스 요리를 주는 고급 레스토랑의 주방장 중심 세계였다면, GraphQL은 주방을 통째로 유리로 만들고 손님(클라이언트)이 재료와 양을 mm 단위까지 지휘하는 셰프 오마카세(손님 중심)의 혁명입니다.
📌 관련 개념 맵 (Knowledge Graph)
| 개념 명칭 | 관계 및 시너지 설명 |
|---|---|
| REST API | GraphQL이 타파하고자 했던 전통적 경쟁 기술이나, 캐싱과 단순성에 있어서는 영원한 벤치마크 대상이자 공존해야 할 아키텍처다. |
| BFF (Backend For Frontend) | MSA 환경에서 여러 백엔드 서버를 묶어 프론트엔드 전용 데이터를 빚어내는 게이트웨이 레이어 패턴으로, GraphQL이 가장 빛을 발하는 무대다. |
| Data Loader (데이터 로더) | GraphQL의 치명적 약점인 N+1 데이터베이스 쿼리 병목 폭주를 막기 위해, 요청을 모아 1번의 쿼리로 병합(Batch) 처리하는 백엔드 필수 구원 투수다. |
| Over-fetching & Under-fetching | REST가 가진 대역폭 낭비(오버)와 네트워크 지연(언더) 문제로, GraphQL의 창조 목적이자 존재 이유 그 자체다. |
| Apollo Client | 서버와 독립된 GraphQL 쿼리를 클라이언트 단에서 정규화(Normalization)하여 로컬 메모리에 맵핑함으로써 HTTP 통신 캐시 한계를 우회하는 1등 공신 라이브러리다. |
👶 어린이를 위한 3줄 비유 설명
- 기존 REST API 식당은 햄버거 세트(서버가 정한 규칙)만 팔아서, 내가 안 먹는 피클(오버패칭)도 무조건 받아야 하고 감자튀김을 더 먹으려면 줄을 두 번(언더패칭) 서야 했어요.
- 하지만 GraphQL 마라탕 가게에서는 종이 1장에 "고기 2장, 채소 빼고, 소스 많이"라고 내가 원하는 딱 그 모양대로만 체크해서 내밀면 한 번에 완벽한 요리가 나와요!
- 그래서 핸드폰(클라이언트)이 불필요한 데이터를 받지 않아서 통신 데이터도 아끼고 화면도 훨씬 빨리 뜰 수 있게 도와주는 똑똑한 주문서랍니다!