2022-05-30,   권재우

이번 포스팅에서는 GraphQL에 대해서 알아보기전에 GraphQL은 새로운 프레임워크, 라이브러리가 아니라, 전혀 새로운 개념이라는 사실을 알아주시면 됩니다. 그럼 GrapQL에 대해서 알아보겠습니다.

GraphQL이란?

이름에 왜 그래프라는 단어가 들어갔을까?
GraphQL 홈페이지 설명

그래프는 근본적인 프로세스에 대한 인간의 뇌 구조와, 언어적인 설명과 비슷하기 때문에 많은 실제 세계의 현상을 모델링하는 강력한 도구입니다.
GraphQL을 사용하면 비즈니스 도메인을 그래프로 모델링 할 수 있습니다.

GraphQL도 SQL(Structed Query Language)과 마찬가지로 페이스북에서 만든 쿼리 언어입니다. 하지만 GraphQL과 SQL은 언어적 구조적에서 매우 차이가 있습니다.
SQL은 데이터베이스 시스템에 저장된 데이터를 효율적으로 가져오는 것이 목적이고,
GraphQL은 웹클라이언트가 데이터 서버로부터 효율적으로 가져오는 것이 목적입니다.

상세한 내용이 궁금하면 아래 GraphQL 공식 홈페이지에서 확인하면 됩니다.
Link: 공식홈페이지

기존 REST API 통신의 한계와 비교

회사에서는 REST API 서버를 구축해서 서비스하는 경우가 있습니다. 그러나 개발하는 서비스의 덩치가 점점 커지면서 여러 한계와 문제점들이 생기게 됩니다

  • 서비스에서 사용하지 않는 불필요한 데이터
  • 특정 기능을 위해 여러번 API가 호출 됨
  • 특정 요청에 fit한 응답을 돌려주기 위해서는 API를 새로 만들어야 함
  • API 유지보수의 어려움
  • PC환경 모바일 환경에 따라 달라지는 데이터

한 문장으로 요약하면, 관리해야 할 EndPoint의 증가로 인하여 발생되는 문제점이라 할 수 있습니다. REST API는 URL, METHOD등을 조합하기 때문에 다양한 EndPoint가 존재합니다. 반면 GraphQL은 단 하나의 EndPoint만 존재합니다.

graphQL1

RESTAPI와 GraphQL API의 사용 (출처 - https://blog.apollographql.com/graphql-vs-rest-5d425123e34b)

기존에 REST API에서는 정보를 얻기 위해 여러번 네트워크를 호출하거나, 다양한 API를 호출해야 했습니다. 하지만 GraphQL은 단 하나의 Endpoint를 제공하며, 단 한 번의 요청으로 모든 정보를 가져 옵니다.

GraphQL 구조

GraphQL의 스키마 쿼리 구조는 C, C++의 헤더파일 과 비슷한 구조를 가집니다.

type Character{
    name: String!
    appearsin: [Episode]!
}
  • 오브젝트 타입 : Character
  • 필드 : name, appearsIn
  • 스칼라 타입 : String, ID, Int 등
  • 느낌표(!) : 필수 값을 의미(non-nullable)
  • 대괄호([, ]) : 배열을 의미(array)

※ 기본 예시

  • GraphQL Query
    {
      user(id: "100") {
          name,
          email
    }
    
  • Response data
    {
      "user": {
          "id": "100",
          "name": "jaewoo kwon",
          "email": "zeus@gamil.com"
    }
    

    ※ SQL비교 예시

  • SQL
      SELECT
      "user"."id" AS "id",
      "user"."email_address" AS "email_address",
      "posts"."id" AS "posts_id",
      "posts"."body" AS "posts_body",
      "user"."first-name" AS "first_name",
      "user"."last_name" AS "last_name"
    FROM accounts AS "user"
    LEFT JOIN posts AS "posts" ON "user",id = "posts".author_id
    WHERE "user".id = 2
    
  • GQL
      {
      user(id: 2) {
      	id
          email
          posts {
          	id
              body
              comments {
              	body
                  author { fullName }
              }
          }
      }
    }
    

    GraphQL의 장점

    위에서 언급한 특징을 기반으로 장점을 정리해 보겠습니다.

1. 하나의 EndPoint

가장 큰 특징이자 장점인 한 개의 EndPoint를 가짐으로써 HTTP 요청의 횟수를 줄일 수 있고 API나 View를 따로 구성할 필요가 없어집니다. 요청을 보낼때는 정해진 한 군데로만 요청을 보내면 되고, 그 외의 API를 신경쓸 필요가 없어져, 유지보수가 용이해집니다.

2. Fit한 Data

GraphQL은 한번의 요청으로 원하는 데이터 전부를 서버로부터 요청하여 가져오기 때문에 REST API만을 사용할 때 발생하는 Overfetching이나 Underfetching등의 문제가 발생하지 않습니다.

  • Overfetching
    원하는 data 이상의 정보를 요청받는 것, data의 정제에 리소스가 낭비

  • Underfetching
    원하는 data의 정보를 요청받기 위해 여러번 요청을 보내는 것, 네트워크를 통해 여러번 접근을 하여 리소스 낭비

3. 기종에 상관없는 API

Facebook에서는 기존에 REST API로 ios, Android에 따라 다른 서비스를 제공하는 API구현이 힘들었다고 합니다. 그래서 기종에 상관없이 표준화 된 쿼리언어를 개발 했습니다.
Link: 자세한설명참조

GraphQL의 단점

GraphQL은 지속적으로 성장하는 생테계로써, 완성된 명세가 존재하지 않습니다.

1. 규모가 작을 때 비효율

고정된 요청과 응답만 필요한 경우에는 Query 요청의 크기가 RESTful API보다 커지게 됩니다. 즉, GraphQL의 장점이 줄어든다고 볼 수 있죠. .

2. 파일 업로드

File 전송 등 Text만으로 하기 힘든 내용들을 처리하기 복잡합니다. (불가능한건 아님)

3. 요청 필터링 어려움

GraphQL은 클라이언트가 필요한 데이터를 스스로 결정하여 요청하게 됩니다. 따라서 GraphQL의 다양한 요청 형태에서 잘못된 요청을 필터링하기가 까다롭습니다.(또한 불가능한건 아님)

※그럼 어떨 때 사용하는것이 좋은가?

어떤것을 사용할지 다음과 같은 기준으로 선택하면 될 것입니다.

GraphQL

  • 서로 다른 모양의 다양한 요청들에 대해 응답할 수 있어야 할 때
  • 대부분의 요청이 CRUD(Create-Read-Update-Delete) 에 해당할 때

RESTful

  • File 전송 등 단순한 Text 로 처리되지 않는 요청들이 있을 때
  • 요청의 구조가 정해져 있을 때

그러나 더 중요한 것은, 둘 중 하나를 선택할 필요는 없다는 것입니다.

GraphQL and RESTful!

File 전송과 같이 RESTful 이 더 유리한 API 가 있을 수 있고, 다양한 정보를 주고받는 것 같이 GraphQL 이 더 유리한 API 가 있을 수 있습니다.

이럴 때 하나의 Endpoint 를 GraphQL 용으로 만들고, 다른 RESTful endpoint 들을 만들어 놓을 수 있습니다. 주의해야할 것은 하나의 기능에 두 API structure 를 섞어놓는 것은 API 성능을 떨어뜨릴수도 있습니다.

GraphQL의 라이브러리

GQL 자체는 쿼리 언어이기 때문에 구체화 할 수 있도록 도와주는 라이브러리를 사용해야 합니다.
두 개의 라이브러리가 있는데 둘 중 아폴로가 편리해서 더 많이 사용합니다.

  • 릴레이(Relay)
  • 아폴로(Aplollo GraphQL)

Reference

  • https://graphql.org/blog/graphql-a-query-language/
  • https://owin2828.github.io/devlog/2020/11/12/GraphQL-1.html#2-graphql%EC%9D%98-%EC%9E%A5%EC%A0%90
  • https://velog.io/@swhan9404/graphQL-%EC%9D%B4%EB%9E%80

업데이트: