GraphQL이란 무엇인가 — REST를 넘는 API 쿼리 언어

모바일 앱이 화면 하나를 그리려고 서버에 대여섯 번씩 요청을 던지던 시절이 있었다. 사용자 정보 한 번, 친구 목록 한 번, 게시글 한 번… 그렇게 받아 온 데이터에는 정작 쓰지 않는 필드가 절반이었다. 이 비효율을 정면으로 겨냥해 등장한 것이 바로 GraphQL이다. API의 쿼리 언어라는 다소 낯선 정체성 탓에 “REST의 대체재” 정도로만 알려져 있지만, 실제로는 데이터를 요청하는 방식 자체를 바꾼 기술이다. 이 글은 GraphQL의 정의와 등장 배경, 스키마·쿼리 같은 핵심 구성 요소, REST와의 차이, 그리고 솔직한 한계까지 입문자 눈높이에서 정리한다. 앞서 다룬 REST API란 무엇인가 글과 짝으로 읽으면 두 방식의 트레이드오프가 더 선명하게 잡힐 것이다.

GraphQL이란 무엇인가

GraphQL은 API를 위한 쿼리 언어이자, 그 쿼리를 서버에서 처리하는 런타임이다. 풀어 말하면, 클라이언트가 “나는 이런 데이터가, 이런 모양으로 필요하다”고 선언적으로 기술하면 서버가 정확히 그 모양대로 응답을 돌려주는 방식이다. 공식 사이트(graphql.org)는 GraphQL을 “API를 위한 쿼리 언어이며 데이터에 대한 정의된 타입 시스템으로 쿼리를 실행하는 서버 측 런타임”이라고 정의한다. IBM 역시 GraphQL을 “클라이언트가 필요한 데이터를 정확히 명시할 수 있게 해 과다·과소 인출을 막는 쿼리 언어”로 설명한다.

역사를 보면 정체성이 더 분명해진다. 위키백과의 정리에 따르면 GraphQL은 2012년 페이스북(현 메타) 내부에서 시작됐다. 뉴스피드를 모바일로 옮기는 과정에서 기존 REST 방식이 한계를 드러냈고, 리 바이런(Lee Byron)·댄 셰이퍼(Dan Schafer)·닉 슈록(Nick Schrock) 세 사람이 주도해 해법을 만들었다. 이 기술은 2015년 React Europe 컨퍼런스에서 공개된 뒤 오픈소스로 풀렸고, 2018년에는 리눅스 재단 산하 GraphQL 재단(GraphQL Foundation) 으로 이관돼 특정 기업의 소유가 아닌 공개 표준이 됐다. 명세는 이후로도 꾸준히 갱신돼 2025년 기준 안정 버전이 유지되고 있다.

여기서 한 가지 오해를 짚고 가면, GraphQL은 데이터베이스 기술이 아니다. SQL과 이름이 비슷해 헷갈리지만, GraphQL은 데이터가 어디에 저장돼 있든(관계형 DB든, 여러 마이크로서비스든, 외부 API든) 그 위에 얹는 요청·응답 규약일 뿐이다.

GraphQL이 등장한 이유 — 오버페칭과 언더페칭

GraphQL을 이해하는 가장 빠른 길은 그것이 풀려고 했던 문제를 보는 것이다. REST API의 고질적인 두 약점, 오버페칭(over-fetching)언더페칭(under-fetching) 이 그 출발점이다.

  • 오버페칭: 화면에는 사용자 이름 하나만 필요한데, /users/42 엔드포인트가 이름·이메일·가입일·프로필 이미지까지 통째로 돌려주는 경우다. 응답 형태가 서버에 고정돼 있어 클라이언트가 필드를 골라 받을 수 없다. 모바일·저속 네트워크에서 특히 손해다.
  • 언더페칭: 반대로 화면 하나를 그리는 데 필요한 데이터가 여러 엔드포인트에 흩어져 있어, 요청을 연달아 여러 번 보내야 하는 경우다. 사용자 정보 → 그 사용자의 게시글 → 각 게시글의 댓글… 식으로 호출이 꼬리를 문다.

구글 클라우드의 비교 문서는 GraphQL이 “엔드포인트가 앱에 필요한 양보다 너무 많거나 적은 데이터로 응답하는 문제를 방지한다”고 설명한다. GraphQL에서는 클라이언트가 필요한 필드를 직접 명시하기 때문에, 한 번의 요청으로 딱 필요한 만큼만 받아 올 수 있다. 비유하자면 REST가 정해진 세트 메뉴라면, GraphQL은 원하는 재료만 골라 담는 샐러드 바에 가깝다.

GraphQL의 핵심 구성 요소

GraphQL의 동작은 크게 네 가지 개념 위에 선다. 스키마, 그리고 세 가지 작업 유형(쿼리·뮤테이션·서브스크립션)이다.

스키마와 타입 시스템

GraphQL 서버의 출발점은 스키마(schema) 다. 스키마는 “이 API가 어떤 데이터를 제공하고, 각 데이터가 어떤 타입인지”를 미리 못 박아 둔 계약서다. 강타입(strongly typed) 시스템이라 클라이언트는 요청을 보내기 전에 어떤 필드가 존재하는지, 그 타입이 무엇인지 알 수 있다. 이 덕분에 자동 완성·문서 생성·유효성 검사 같은 개발 도구가 풍부하게 동작한다.

type User {
  id: ID!
  name: String!
  email: String
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
}

쿼리·뮤테이션·서브스크립션

GraphQL의 작업은 세 종류로 나뉜다.

  • 쿼리(Query): 데이터를 읽는다. REST의 GET에 해당한다.
  • 뮤테이션(Mutation): 데이터를 생성·수정·삭제한다. REST의 POST/PUT/DELETE를 아우른다.
  • 서브스크립션(Subscription): 서버의 데이터가 바뀔 때 실시간으로 알림을 받는다. 채팅·알림처럼 양방향 통신이 필요한 곳에 쓰인다.

그리고 이 요청을 실제 데이터와 연결해 주는 함수가 리졸버(resolver) 다. 클라이언트가 userposts를 요청하면, 서버는 각 필드에 매핑된 리졸버를 호출해 값을 채워 응답을 조립한다.

GraphQL 쿼리, 어떻게 생겼나

개념을 코드로 보면 단번에 이해된다. 아래는 “42번 사용자의 이름과, 그 사용자가 쓴 글의 제목만” 요청하는 쿼리와 응답이다.

query {
  user(id: "42") {
    name
    posts {
      title
    }
  }
}
{
  "data": {
    "user": {
      "name": "itinsights",
      "posts": [
        { "title": "GraphQL 입문" },
        { "title": "REST API 정리" }
      ]
    }
  }
}

요청한 필드(name, posts.title)와 응답의 구조가 정확히 같다는 점에 주목하자. email이나 사용자의 다른 정보는 요청하지 않았으니 응답에도 없다. 이것이 GraphQL의 핵심 매력, 즉 응답의 모양을 클라이언트가 결정한다는 특성이다. 게다가 이 모든 요청은 보통 /graphql이라는 단일 엔드포인트로 들어간다. REST가 자원마다 주소를 나누는 것과 대비되는 지점이다.

GraphQL vs REST — 무엇이 다른가

두 방식의 성격을 한눈에 비교하면 다음과 같다. (REST API의 6대 제약과 HTTP 메서드는 별도 글에서 자세히 다뤘다.)

구분 REST GraphQL
엔드포인트 자원마다 여러 개 보통 단일 엔드포인트
데이터 형태 서버가 고정 클라이언트가 쿼리로 지정
오버/언더페칭 자주 발생 구조적으로 회피
HTTP 캐시 메서드·상태코드로 활용 쉬움 직접 구현해야 함
러닝 커브 낮음 상대적으로 높음
타입 안정성 별도 규약 필요 스키마로 기본 제공

Apollo를 비롯한 GraphQL 진영은 “더 나은 REST”라는 표현을 쓰지만, 2026년 시점의 현실적인 평가는 “우열이 아니라 용도”에 가깝다. 한 가지 짚어 둘 점은, GraphQL이 REST를 대체했다는 통념과 달리 공개 API 영역에서는 여전히 REST가 압도적 다수를 차지한다는 사실이다(구체 점유율은 출처마다 편차가 커 단정하긴 어렵다). GraphQL은 데이터 요구가 복잡한 프런트엔드, 여러 백엔드를 하나로 모으는 게이트웨이 계층에서 강점을 발휘한다.

GraphQL의 한계와 단점

균형을 위해 단점도 분명히 짚어야 한다. GraphQL은 만능이 아니며, 잘못 도입하면 오히려 복잡도만 키운다.

  • 캐싱이 까다롭다: REST는 URL과 HTTP 상태 코드만으로 브라우저·CDN 캐시를 공짜로 누린다. GraphQL은 대부분의 요청이 같은 엔드포인트로 들어가는 POST라, 이 인프라를 그대로 쓰기 어렵고 별도 캐싱 전략이 필요하다.
  • N+1 문제: 리졸버가 필드마다 데이터를 따로 조회하다 보면, 목록 하나를 그리는 데 데이터베이스 쿼리가 수십 번 발생할 수 있다. DataLoader 같은 배칭 도구로 완화하지만 신경 써야 할 지점이다.
  • 러닝 커브와 과설계: 스키마 설계, 리졸버 구현, 쿼리 복잡도 제한 등 익혀야 할 개념이 많다. 단순한 CRUD 백엔드라면 REST가 훨씬 간결하다.
  • 요청 비용 제어: 클라이언트가 자유롭게 깊은 쿼리를 던질 수 있다는 건 곧 악의적으로 무거운 쿼리도 가능하다는 뜻이다. 쿼리 깊이·복잡도 제한 같은 방어 장치가 별도로 필요하다. AWS의 비교 설명도 GraphQL의 유연성이 캐싱·쿼리 비용 관리라는 새로운 과제를 동반한다고 지적한다.

정리하면, 클라이언트의 자유를 키운 대가로 서버 쪽 책임과 운영 난도가 함께 올라간다. 도입 전에 “우리 서비스가 정말 이 유연성을 필요로 하는가?”를 먼저 물어야 하는 이유다.

GraphQL, 언제 써야 하나

정리하면, GraphQL은 클라이언트가 필요한 데이터의 모양을 직접 정의하게 함으로써 REST의 오버페칭·언더페칭을 구조적으로 해결한 API 쿼리 언어다. 단일 엔드포인트, 강타입 스키마, 선언적 쿼리라는 특성이 복잡한 데이터 요구를 가진 애플리케이션에서 빛을 발한다.

그렇다면 모든 프로젝트에 GraphQL을 써야 할까? 그렇지 않다. 화면마다 다양한 데이터 조합이 필요한 모바일·복합 프런트엔드, 여러 마이크로서비스를 하나의 API로 묶는 게이트웨이라면 GraphQL의 유연성이 비용을 정당화한다. 반대로 단순한 자원 조회가 대부분이고 캐싱이 중요한 공개 API라면, 검증된 REST API가 여전히 더 무난한 선택이다. 실제로 많은 팀이 둘을 함께 쓰는 하이브리드 구성을 택한다.

여러분이 지금 설계 중인 API는 데이터 요구가 복잡한 편인가, 아니면 정형화된 CRUD에 가까운가? 도구의 유행이 아니라 트레이드오프를 기준으로 고르는 것이 핵심이다. 기술 환경과 팀 역량에 따라 최적의 선택은 달라질 수 있으니, 본 정리는 판단의 출발점으로 활용하길 권한다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다