프로젝트 개요

프로젝트를 진행하면서 가장 메인이된 기술은GraphQL입니다.
이에, GraphQL이 무엇인지 알아보는 포스트를 작성해 보고자 합니다.

GraphQL을 선택한 이유

코드스테이츠에서 이머시브 코스를 수강하는 중에는 REST API를 학습했었습니다.
그러다 같이 프로젝트를 진행한 팀원을 통해 GraphQL에 대해서 알 수 있는 기회가 있었고 GraphQL이 무엇인지도 모른 채 프로젝트를 시작하게 되었습니다.

프로젝트를 진행하며 REST APIGraphQL의 차이를 조금이나마 겪어볼 수 있었습니다.

GraphQL 이란?

1. GraphQL(Graph Query Language)

REST API 와 같이 서버로부터 데이터를 응답받기 위하여 어떤 방식으로 요청할지에 대해서 정의한 문법으로, 페이스북에서 만들어졌습니다.

2. GraphQL의 탄생 배경

  • FaceBook의 서비스 구동 환경의 다양성 (Android, IOs, Web 환경 등 )

  • 다양한 구동 환경에 의한 호환성 문제

    • 각 구동 환경마다 필요한 데이터의 형태가 같지 않다는 문제
    • 응답받을 데이터의 형태가 같지 않다면 요청에 대한 endpoint가 그만큼 늘어나야함
  • 모바일 환경과 웹 환경에서의 API들을 일일히 구현 해야하는 어려움

3. FaceBook이 내놓은 해결책

단순하게 하나의 응답만을 반환하는 다수의 EndPoint가 아니라
동적으로 변하는 응답을 반환하는 단 하나의 EndPoint!

4. GraphQL이 REST API 보다 나은 확실한 장점 2가지!

1. OverFetching

OverFetching이란 불필요한 데이터까지 응답으로 받아오는 REST API의 단점중 하나입니다.
예를 들어, 특정 유저의 정보를 요청하는 request를 /users/1로 가정하고
현재 원하는 정보는 그 안에 있는 userName이라 할 때,

{
    userName: "jake",
    email: "jake@naver.com",
    profileImage: "url"
}

그러면 Server는 작성해놓은 EndPoint에 의해 userName만 필요한 상황이지만
불필요한 데이터인 email과 profileImage까지 응답으로 받게 됩니다.
REST API에서 이 OverFetching 문제를 해결하려면 userName만 응답으로 반환하는 API를 따로 구현을 해야합니다.
하지만 이 방법은 새로운 EndPoint를 생성해야 하기 때문에 좋지 않은 방법이라고 생각합니다.
이러한 OverFetching 문제는 GraphQL에서 해결이 가능합니다.

2. UnderFetching

UnderFetching이란 여러 종류의 데이터를 받기 위해 여러번의 요청을 보내는 문제를 말합니다.
예를 들어 화면을 구성하는 요소 중에 유저의 이름, 게시글 목록, 현재 접속한 유저들의 목록을 띄우고 싶다면
/boards, /users/1, /users 로 request를 보내야 합니다.
결국에는 한 화면을 구성하기 위해서 총 3번의 요청을 보내는 문제가 생깁니다.
GraphQL은 이 request들을 모아서 한 번에 요청을 보낼 수 없습니다.

5. GraphQL의 요소

  1. Query

    • Query는 Server로 보내는 요청입니다.
      // 서버로 쿼리문의 형태로 요청을 보냅니다.
      query {
        convenienceStore {
          apple,
          pork
        }
      }
    • Query 요청은 다른 사람에게 부탁을 하는것 (요청)
    • 그리고 그 요청은 한 번에 여러가지도 가능
      query {
        convenienceStore {
            apple,
            pork
        },
        tailorShop { // 한 번의 요청에 다른 종류의 데이터를 받아 올 수 있습니다.
            shoes
        }
      }
    • REST API의 UnderFetching 문제를 해결 가능
    • 부탁(요청)의 내용 또한 언제든 변경 가능
      query {
       convenienceStore { // 받아올 데이터의 형태가 달라졌습니다.
           snack  
       },
       tailorShop {
           shoes
       }
      }
      같은 EndPorint로 요청을 보내더라도 받아올 데이터의 형태 변경 가능
      = REST API의 OverFetching 문제 해결
  2. Mutation

    • Client에서 Component의 변경이 있을 경우 사용하는 Quary
      mutation ($item: String!, $price: Int!) {
        convenienceStore (item: $item, price: $price){
            apple,
            pork
        },
        tailorShop { // 한 번의 요청에 다른 종류의 데이터를 받아 올 수 있습니다.
            shoes
        }
      }
    • 입력될 데이터의 타입을 정하여 서버로 전송합니다.
  3. Schema

    • GraphQL의 Schema는 Database의 Schema와 유사합니다.
      type Query {
        convenienceStore: { 
            pork: String!
            apple: String!
            snack: String!
        }
        tailorShop: {
            suit: String!
            shoes: String!
        }
      }
    • 요청을 받았을 때 어떤 속성을 어떤 타입으로 반환할지에 대한 정의
  4. Resolver

    • Resolver는 실제로 데이터를 반환하는 부분입니다.
      export default{
        Query: {
          convenienceStore: (root, args, context, info) => {
              return {
                 pork: "Pork!",
                 apple: "Apple!",
                 snack: "Snack!"
              }
          },
          tailorShop: (root, args, context, info) => {
             return {
                shoes: "Shoes!",
                suit: "Suit!"
             }
          }
        }
      }
      Resolver가 바로 REST API의 Controller라고 생각하면 될 것 같습니다.
      Resolver로 원하는 데이터만을 Query로 작성하여 요청을 보내면 Resolver에서 데이터를 응답으로 반환합니다.

마무리

GraphQL은 REST API의 상위 호환이 아니며 REST API를 대체할 수 있는 하나의 스펙이라고 생각합니다.
두 가지 방식의 장단점을 잘 파악하여 GraphQL만을 사용한 서버 혹은 REST API만을 사용한 서버 그것도 아니라면 두 가지 모두 혼용한 서버를 구축할지 설계를 해야할 것 입니다.