GraphQL

[GraphQL] 개념 정리 (REST API와 비교)

sihanni 2025. 8. 10. 20:44

 

GraphQL 이란?

GraphQL은 페이스북에서 만든 쿼리 언어이며 서버 측 런타임이다. 클라이언트가 필요한 데이터만 요청할 수 있도록 설계되어 있어, REST API보다 유연하고 효율적인 데이터 fetching이 가능하다.

SQL은 데이터베이스 시스템에 저장된 데이터를 효율적으로 가져오는 목적이라면, GQL은 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것이 목적이다.

우선 GraphQL은 웹 클라이언트가 데이터를 서버로부터 효율적으로 가져오는 것이 목적이라는 정도만 알아두고 차근차근 알아가보기로 했다.

등장 배경

2012년 페이스북이 만든 API 쿼리 언어이자 런타임인 GraphQL은 2015년에 처음 오픈소스로 공개되었으며,

REST API의 한계를 해결하기 위해 등장했다.

 

REST API의 주요 한계

  • Over-fetching (불필요한 데이터까지 받음)
    • 예: /users/1 요청 → 유저의 모든 정보가 오지만, 내가 필요한 건 name 하나뿐..
  • Under-fetching (원하는 데이터를 다 못 받아서 여러 번 호출 필요)
    • 예: 유저 정보 + 그 유저의 게시글 + 게시글 댓글 → REST에서는 보통 3번 호출 필요
  • 버전 관리 문제
    • REST는 /v1, /v2처럼 버전 API를 새로 만들어야 함
  • 프론트엔드 맞춤 데이터 제공 어려움
    • 같은 API라도 모바일, 웹, 관리자 페이지에서 필요로 하는 데이터가 다름
  • 서비스 규모가 커질수록 많아지는 엔드포인트
    • REST는 자원 중심 설계이기 때문에, 각 리소스별로 필요한 기능마다 새로운 엔드포인트가 필요한 경우가 많다.
    • 엔드포인트가 불어나는 것과 비례하여 API 문서 관리 복잡도도 같이 올라간다.
    • 비슷한 데이터 조회지만 엔드포인트마다 비즈니스 로직이 반복될 수 있다.
    • 프론트엔드 측에선 화면에 필요한 데이터를 위해 여러 엔드포인트를 조합 호출 해야한다.

GraphQL과 REST의 차이점은?

비교 항목 REST API GraphQL
요청 방식 여러 엔드포인트 하나의 엔드포인트
데이터 구조 서버에서 정의 클라이언트가 필요한 필드 구조를 쿼리로 정의
데이터 가져오기 고정된 구조 응답 원하는 필드만 응답
Over-fetching 자주 발생 (필요 없는 필드가 포함될 수 있음) 거의 없음 (원하는 필드만 요청)
Under-fetching 자주 발생
(원하는 데이터 조합을 위해 여러 API 호출)
거의 없음
(한 번의 요청으로 다양한 데이터 조합 가능)
버전 관리 /v1, /v2 필요 스키마 확장 & 필드 Deprecation으로 대응
문서화 Swagger 등 별도 필요 스키마 자체가 문서
실시간 데이터 별도 구현 (WebSocket 등) Subscription 내장
캐싱 HTTP 캐싱 활용 간단 필드 단위 응답이라 캐싱이 상대적으로 복잡함
(쿼리 기반의 캐싱이 필요)
보안 엔드포인트 단위 권한 처리가 용이함 필드 단위 권한 처리 필요(설계 난이도 상승)

 

REST API

  • 자원별 URL + 고정 응답이 장점으로 단순하고 캐싱이 쉽다.
  • 하지만 Over/Under-fetching과 엔드포인트 폭증 문제가 있다.

GraphQL

  • 단일 엔드포인트 + 클라이언트 정의 응답으로 유연하고 데이터 최적화가 가능하다.
  • 하지만 서버 부담이 커질 수 있고, 캐싱 및 보안 설계가 더 복잡해진다.

주요 구성 요소

구성 요소 설명 예시
Schema API의 타입 정의서
Query, Mutaion, Subscription이 포함
schema.graphql
Type 데이터 구조 정의.필드명과 타입 지정 type User { id: ID!, name: String! }
Query 데이터 조회(읽기) 작업 user(id: 1) { name }
Mutation 데이터 변경(쓰기) 작업. 생성, 수정, 삭제 포함 createUser(name: "Alice") { id }
Subscription 실시간 데이터 스트리밍 postAdded { id title }
Resolver 각 필드의 실제 데이터 조회/변경 로직 구현 user: (parent, args) => db.findUser(args.id)
Scalar Type 기본 자료형 Int, Float, String, Boolean, ID
Input Type Mutation에 전달할 입력 데이터 구조  


기본적인 동작 구조

1. 클라이언트가 쿼리를 작성

query {
  user(id: 1) {
    name
    posts {
      title
    }
  }
}
  • 필요한 데이터 구조를 명시

2. GraphQL 서버가 스키마 기반으로 요청을 검증

  • 문법, 타입, 필드 존재 여부 검사

3. 각 필드의 Resolver 실행

  • ex: user Resolver -> DB에서 user 데이터 조회
  • ex: posts Resolver -> 해당 유저의 게시글 목록 조회

4. 데이터 조합 & JSON 응답

  • 모든 필드의 결과를 요청 구조에 맞춰 조립
{
  "data": {
    "user": {
      "id": "1",
      "name": "마루",
      "posts": [
        { "title": "GraphQL 간단 정리" },
      ]
    }
  }
}

 

 

GraphQL 사용시 주의점

Deep Nesting (과도한 네스팅)

query {
  user(id: 1) {
    posts {
      comments {
        author {
          posts {
            comments { ... }
          }
        }
      }
    }
  }
}
  • GraphQL은 클라이언트가 원하는 만큼 필드를 중첩 요청할 수 있다.
  • 하지만 과도하게 깊은 쿼리는 N+1 문제나 쿼리 실행 시간 증가를 유발한다.
  • 대응
    • 쿼리 깊이 제한 (Query Depth Limit) 설정
    • DataLoader로 batch 처리
    • 필요한 depth만 허용하는 규칙 정의

N+1 문제

  • 필드별 Resolver에서 DB를 개별 호출하는 경우 발생
  • ex: 게시글 10개 -> 각 게시글의 작성자를 DB에서 10번 조회 -> 총 11번 쿼리
  • 대응
    • DataLoader을 사용해서 동일 요청을 batch 처리
    • SQL JOIN, ORM의 eager loading 활용
    • 캐싱

쿼리 복잡도 

  • 클라이언트가 쿼리를 너무 크게 작성하면 서버 리소스를 과다하게 사용
  • ex: 수천 개의 레코드를 한 번에 요청하는 쿼리
  • 대응
    • 필드별 가중치 부여 후 총 복잡도 계산
    • 일정 복잡도 이상은 요청 거부
    • 페이징 강제 적용

캐싱 

  • REST는 URL 기반 캐싱이 쉬움 (/users/1)
  • GraphQL은 요청이 POST 방식 + 쿼리 구조/변수에 따라 응답이 달라져 캐싱이 어려움
  • 대응
    • Apollo Client/InMemoryCache 사용
    • Persisted Query(쿼리 해시 기반)
    • 서버측 캐싱 시 쿼리 문자열 키로 활용

권한 처리 

  • REST는 엔드포인트 단위로 권한을 걸기 쉬움.
  • GraphQL은 하나의 엔드포인트에 모든 요청이 들어오기 때문에 필드 단위 권한 체크가 필요함
  • 대응
    • Resolver 단위에서 권한 체크
    • 스키마 레벨 Directive (@auth) 적용
    • GraphQL Shield 같은 권한 관리 라이브러리 사용

서버 부하 제어

  • GraphQL은 클라이언트가 필드 구조를 자유롭게 설계하므로, 서버에 큰 부하를 줄 수 있음.
  • 대응
    • 요청당 필드 수 제한
    • 요청당 실행 시간 제한
    • 결과 크기 제한

 

 

 


같이 읽으면 좋은 글

https://sihanni.tistory.com/140

 

[WEB] REST, RESTful API

REST 개요 REpresentational State Transfer웹에서 리소스를 일관성 있고 예측 가능한 방식으로 다루기 위한 웹 아키텍처 스타일.REST는 프로토콜이나 표준이 아니라, HTTP를 기반으로 한 설계 원칙과 아키텍

sihanni.tistory.com

 



'GraphQL' 카테고리의 다른 글

[GraphQL] 티켓 예매 시스템 어드민 개발  (1) 2025.08.10