GraphQL이란? RESTful API와의 차이점부터 기본 개념까지 정리!

GraphQL이란?

먼저, GraphQL이 어떻게 등장하게 되었는지 살펴보자.

GraphQL(Query Language) 은 페이스북(Facebook)이 2012년 내부 프로젝트로 개발한 후, 2015년에 오픈소스로 공개한 API 쿼리 언어다.

페이스북은 처음에 RESTful API를 활용해 데이터를 제공했지만, 안드로이드, iOS 등 다양한 클라이언트마다 필요한 데이터의 형태가 달랐다.

이로 인해 각 클라이언트에 맞춰 개별적인 API를 개발해야 했고, 시간이 지날수록 API 엔드포인트가 증가하면서 유지보수 비용도 급격히 증가했다.

이 문제를 해결하기 위해, 클라이언트가 원하는 형태로 데이터를 요청하고 수정할 수 있는 쿼리 언어인 GraphQL이 탄생했다.

그렇다면, GraphQL은 RESTful API와 어떤 차이점이 있을까?

GraphQL vs RESTful API

차이점을 표로 한번 정리해봤다.

비교 항목 GraphQL REST API
데이터 요청 방식 원하는 데이터만 요청 가능 정해진 구조의 데이터 반환
엔드포인트 개수 1개 (단일 엔드포인트) 여러 개 (리소스별 엔드포인트)
Over-fetching 문제 ❌ 해결됨 (필요한 데이터만 요청) ✅ 발생 가능 (불필요한 데이터 포함)
Under-fetching 문제 ❌ 해결됨 (한 번 요청으로 필요한 데이터 가져옴) ✅ 발생 가능 (추가 요청 필요)
버전 관리 필요 없음 (단, 이전 버전 API와 호환성 필요) 필요함 (API 버전 v1, v2 등)
오류 검사 잘못된 요청은 스키마 구조로 거부(이로 인해 오류 메시지 자동 생성) 클라이언트 측에서 반환된 데이터 유효성 검사 필요

Query, Mutation, Subscription 개념 및 예제

간단하게 3가지 개념을 간단한 예제를 통해 알아보자.

Query

GraphQL에서 Query는 데이터를 조회(읽기)할 때 사용한다. REST API의 ‘GET’ 요청과 유사하지만, Query Language이기 때문에 SQL의 ‘SELECT’문처럼 필요한 데이터만 선택적으로 가져올 수 있다.

REST API 방식

  • 요청
    GET /users/1
    
  • 응답
    {
      "id": 1,
      "name": "kyeonkim",
      "email": "kyeonkim@example.com",
      "location": "Seoul"
    }
    

    -> Over-fetching 발생: 클라이언트가 ‘name’과 ‘email’만 필요해도, 불필요한 ‘location’ 값까지 포함된다. ‘email’만 가져오려면 기존 메서드를 수정하거나 새로운 API 엔드포인트를 추가해야 한다.
    -> Under-fetching 발생: 반대로, ‘name’만 가져오는 메서드를 만들었는데 사용자 전체 정보가 필요해지면, 별도의 API 엔드포인트를 또 추가해야 한다.

GraphQL 방식(사용자 데이터 요청)

  • 요청
    query {
      user(id: 1) {
        name
        email
      }
    }
    
  • 응답
    {
      "data": {
          "user": {
            "name": "kyeonkim",
            "email": "kyeonkim@example.com"
          }
      }
    }
    

    -> 필요한 데이터만 가져올 수 있다.(Over-fetching, Under-fetching 해결!)
    -> 서버는 만들어두기만해도 클라이언트가 입맛대로 데이터 구조를 정의해서 가져올 수 있다.

Mutation

Mutation은 데이터를 변경(쓰기)할 때 사용된다. REST API에서 ‘POST’, ‘PUT’, ‘DELETE’ 요청과 유사하다.

REST API 방식(새 사용자 추가)

  • 요청
POST /users
Content-Type: application/json

{
  "name": "kyeonkim",
  "email": "kyeonkim@example.com"
}
  • 응답
    {
      "id": 1,
      "name": "kyeonkim",
      "email": "kyeonkim@example.com"
    }
    

GraphQL 방식

  • 요청
    mutation {
      createUser(name: "kyeonkim", email: "kyeonkim@example.com") {
        id
        email
      }
    }
    
  • 응답
    {
      "data": {
          "createUser": {
            "id": 1,
            "email": "kyeonkim@example.com"
          }
      }
    }
    

    -> GraphQL은 요청에서 어떤 데이터를 반환받을지 선택할 수 있다!

Subscription

Subscription은 실시간 데이터를 업데이트할 때 사용된다. WebSocket 기반으로 동작하며, 채팅, 알림 시스템, 실시간 데이터 스트리밍에 활용할 수 있다.

간단한 채팅 예시를 보며 익숙해져보자.

  1. A, B, C가 아래 subscription을 통해 ‘chatRoom’을 구독을 했다.
    subscription {
     chatRoom {
         id
         content
         sender
     }
    }
    
  2. C가 채팅방에 메시지를 보낸다.
    mutation {
     sendMessage(content: "아~반갑고", sender: "반갑이") {
         id
         content
         sender
     }
    }
    
  3. C는 현재 ‘chatRoom’을 구독한 상태이므로 A, B는 자동으로 메시지를 받는다.
    {
      "data": {
            "chatRoom": {
                "id": 1,
                "content": "아~반갑고",
                "sender": "반갑이"
          }
      }
    }
    

즉, A, B, C는 같은 채팅방을 구독하고 있기 때문에, A와 B가 따로 요청하지 않아도 C가 메시지를 보낼 때마다 자동으로 데이터를 받을 수 있다.

GraphQL vs REST API, 어떤 걸 선택할까?

GraphQL이 유리한 경우

  • 클라이언트마다 필요한 데이터가 다를 때 → Over-fetching & Under-fetching 문제 해결
  • API 엔드포인트가 너무 많을 때 → 단일 엔드포인트로 효율적 관리
  • 대역폭이 제한되어 있으며 요청 및 응답 수를 최소화하려는 경우

REST API가 유리한 경우

  • 애플리케이션 규모가 작고 데이터가 덜 복잡한 경우 → 학습 비용이 적고 캐싱이 쉬움
  • 모든 클라이언트에서 유사하게 사용되는 데이터와 작업이 있는 경우
  • 복잡한 데이터 쿼리가 필요 없는 경우

마무리

GraphQL은 REST API의 한계를 보완하며, 필요한 데이터만 요청하고 단일 엔드포인트로 효율적으로 관리할 수 있는 강력한 쿼리 언어다. 하지만, 복잡한 쿼리는 서버 부하를 증가시킬 수 있으며, 캐싱 및 보안 관리가 필요하다는 점도 고려해야 한다.

항상 생각하지만 개발자는 상황에 따라 적절한 방식을 선택하는 것이 중요하다!

참조

https://www.youtube.com/watch?v=xiE9-S7s9rs
https://chanhuiseok.github.io/posts/gql-1/
https://aws.amazon.com/ko/compare/the-difference-between-graphql-and-rest/ https://graphql.org/learn/

Categories:

Updated:

Leave a comment