ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • GraphQL이란?
    2019. 9. 13. 20:07

    GraphQL은 facebook에서 만든 Graph Query Language로 어플리케이션 레이어 쿼리 언어입니다. 다시 말해서 API를 위한 쿼리 언어이며 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임입니다. GraphQL은 특정한 데이터베이스나 스토리지에 귀속되어 있지 않으며 기존 코드와 데이터에 의해 대체됩니다.

    GraphQL은 기존에 사용하고 있는 REST API의 한계점을 극복하고자 나온 통신 규약으로 REST API를 대체할 수 있습니다. 아래에서 REST API의 한계점과 GraphQL이 무엇인지 설명합니다.

    REST API의 한계

    REST API의 개념을 간단하게 말하자면 모든 Resource들을 하나의 Endpoint에 연결하고 연결된 Endpoint는 Resource와 관련된 내용만 관리하게 하는 것입니다. 단순한 서비스에서는 아주 좋지만 복잡한 서비스나 클라이언트의 요청사항에 따라 Over-Fetching과 Under-Fetching이 발생합니다. 또한 REST API로 여러 환경에서 필요한 정보들을 Resource별로 Endpoint를 갖도록 구현하는 것이 어렵습니다. 한 마디로 비슷하지만 Endpoint가 다른 API가 많이 파생됩니다.

    Over-Fetching

    예를 들어, 사용자의 데이터를 조회하는 /user/ API가 있다고 가정합니다. 이 때, 사용자 번호: 1 에 해당하는 데이터를 조회한다면 아래와 같은 형태가 됩니다.

    GET /user/1/
    response body 
    {
     "user_no": 1,
     "user_name": "test",
     "usere_grade": "VVIP",
     "zip": "11053",
     "last_login_timestamp": "2019-08-08 12:11:44",
     ...
    }


    여기서 클라이언트에서는 1번에 해당하는 유저의 이름만을 사용하고자 한다고 해도 유저 이름만 반환하는 API가 없다면 위와 같은 /user/1/ API를 호출한 다음, user_name을 가져와 사용해야 합니다. 이때, user_grade, zip 등등의 데이터는 사용하지 않는 데이터도 같이 반환받습니다. 이는 곧 리소스의 낭비라고 볼 수 있고 이와 같은 낭비를 Over-Fetching이라 칭합니다.

    Under-Fetching

    쇼핑몰 서비스의 경우, 로그인한 사용자의 장바구니 정보를 보여준다고 가정하면 여러 API를 호출하게 됩니다.

    /user/1/

    /cart/

    /notification/

    /wish/

    ...


    요청에 맞게 유효한 데이터를 보여주기 위해 여러 API를 호출하게 되는 경우를 Under-Fetching이라 합니다.

    REST API 목록

    REST API 방법론으로 API를 만든다고 하면 Resource 별로 Endpoint를 갖기 때문에 비슷하지만 다른 API를 생성하게 됩니다.

    /item/

    /item/detail/

    /item/image/

    /item/notice/

    /item/manage/

    ...


    이는 서비스가 커져갈 때 관리 포인트가 늘어나게 되므로 개발자나 클라이언트에게 부담이 됩니다.

    GraphQL

    GraphQL은 위에서 설명한 것처럼 REST API의 한계를 극복하고자 나왔습니다. Endpoint는 통상 1개만 생성하고 클라이언트에게 필요한 데이터는 클라이언트가 직접 쿼리를 작성, 호출하여 반환 받습니다.


    위의 Under-Fetching 문제를 GraphQL을 사용하면 손쉽게 해결됩니다.

    요청 쿼리

    query {
     user(user_no: 1) {
     user_name
     }
    }

    반환 데이터

    {
      "data": {
        "user": {
          "user_name": "jim",
        }
      }
    }


    또한 Over-Fetching 문제도 GraphQL을 사용해 해결할 수 있습니다.

    요청 쿼리

    query {
     cart {
     product_name
     price
     }
     notification {
     is_read
     }
     user(user_id: 1) {
     user_name
     user_grade
     }
    }

    반환 데이터

    {
      "cart": [{
        "product_name": "shoes",
        "price": 12000
      }, ...],
      "notifications": [{
        is_read: true
      }],
      "user": {
        "user_name": "jim",
        "user_grade": "VVIP"
      }
    }

    장점

    • 클라이언트가 필요한 데이터만 반환할 수 있음
    • 1번의 호출로 원하는 데이터를 한번에 가져올 수 있음
      • REST API의 N+1 Problem을 해결 할 수 있음.
    • 확장이 용

    단점

    • 백엔드, 클라이언트 개발자 양쪽 다 러닝커브가 있음

    • 단순한 서비스에서는 사용하기가 복잡함
    • 캐싱 기능의 구현이 복잡
      • 대부분의 언어에서 라이브러리로 제공함
    • 요청이 text로 날라가기 때문에 File 전송 등을 구현하기가 어려움

    요약

    GraphQL은 REST API의 한계점을 해결하고자 나온 통신 규약. 하지만 무조건 GraphQL이 REST API보다 낫다는 것이 아니므로 서비스 별로 잘 판단하여 레이어를 선택하는 것이 중요

    공식 문서

    https://graphql.org/

    https://graphql-kr.github.io/

    댓글