성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

GraphQL

[GraphQL] 1. 기초 개념 및 배경지식

제이콥(JACOB) 2019. 12. 9. 00:29

GraphQL이 뭐지?

API를 만들 때 사용할 수 있는 쿼리 언어이며, 서버측 런타임이다.

image


뭐 이렇게 생긴? (GraphQL 메인에 있는 사진이다;;) 언뜻보면 그냥 JSON처럼 보인다. 그 말은 어려워 보이진 않고 친숙하다는 말이다! 벌써 배워보고 싶은 욕구가 넘친다 :) 그리고 불과 몇 년전에 페이스북에서 만든 만큼 트랜디하며, 이미 페이스북 내부의 데이터 페칭을 거의 GraphQL로 이루어 지고 있다!

GraphQL 쿼리는 실제 필요한 데이터만 받도록 작성할 수 있다. URL에서 GraphQL 쿼리를 전송하여 유효성을 검사하고 실행할 수 있다.

{
  hero {
    name
  }
}

간단히 말해서 이렇게 보내면

{
  "data": {
    "hero": {
      "name": "R2-D2"
    }
  }
}

이게 GraphQL의 핵심이다. 쿼리와 결과가 정확히 동일하다! 이는 서버에서 클라이언트가 요청하는 필드를 정확히 알고 있기 때문이다. (놀랍지 않은가? Rest한 방식으로 데이터를 받던게 생각이 나지 않는다면 아래서 한번 보여주겠다) 여튼 이렇게 데이터를 받을 수 있다. 여기까지만 보면 굳이 뭐 크게 다른거 같지는 않다. 'GET, POST 등의 REST한 방식을 언급하지 않았다?' 뭐 이정도다. 조금 더 자세히 보면 왜 좋은지 알 수 있을거다.

 

Schema (스키마 정의)

GraphQL 서버에서는 쿼리가 실행될 때마다 타입 시스템에 기초하여 쿼리가 유효한지 검사를 한다. 그리고 그런 서비스를 만들려면 GraphQL Schema에서 데이터 타입을 정의해 주면 된다.

type Person {
  id: ID!
  image: String
  name: String
  nick_name: String
  gender: String
  phone_number: String
  age: Int
  memo: String
  height: Int
  created: String
  edited: String
  roll: String
}

각 필드에는 필드의 타입과 함께 정의했다. 아직은 작성 방법은 제대로 몰라도 된다. 하지만 이해가 안되는 코드는 아님이 분명하다.

 

선언형 데이터 페칭 언어

GraphQL은 흔히 선언형 데이터 페칭(fetching) 언어라고 한다. 개발자는 무슨 데이터가 필요한지에 대한 요구사항만 작성하면 되고 어떻게 가져올지는 신경 쓰지 않아도 된다는 것이다. 그리고 다양한 서버 라이브러리를 지원한다. (GO, JAVASCRIPT, JAVA, C#, PYTHON, Ruby 등...)

 

GraphQL은 REST API의 완벽한 대체재다?

결론부터 말하면 아니다. REST API도 데이터 전송 역사에서 큰 부분을 차지하며, 아직까지도 많이 사용되고 있다. REST의 특정 부분(부하 완화 등)을 보완해 주는 것이다(물론 몇 년후에는 모르겠지만...). 일단 REST API의 단점부터 찾아보자.

Over Fetching (오버페칭)

위에서 사용한 스키마를 그대로 사용해 보겠다.


우리는 앱을 만들고 있고 화면에 데이터를 보여준다고 가정해 보자.

image


유저 상세 화면이 아닌 간단한 유저 정보만 보여주는 화면이기 때문에 {이미지, 이름, 닉네임}만 있으면 된다.
REST API라면 나는 서버로 아래와 같은 GET 요청을 보낼 것이다.

// 예시, 이런 주소 없어요
https://master-jung-api.com/person/1

그럼 응답으로 아래와 같은 JSON 데이터를 받게 된다.

{
  image: 'hosting.jpg',
  name: '정규현',
  nick_name: 'Jacob',
  gender: 'men',
  phone_number: '010...',
  age: 28,
  memo: 'hi!',
  height: 200
  created: '2019-08-31',
  edited: '2019-09-14',
  roll: 'user',
}

내가 필요한 데이터보다 훨씬 더 큰 데이터를 받았다. 내가 필요한 데이터는 딱 세개뿐이었는데...
물론 "저 데이터 용량이 얼마나 하고 몇 바이트나 늘어난다고" 라고 생각할 수 있지만, 과연 저게 효율적인가? 데이터가 만약 많다면? 또같은 공수 혹은 더 적은 공수로 개선할 수 있다면? 개발자로서 욕심(????)이 있다면?(^^;;) 마음이 바뀐다. 어떻게 해야될까.

이때 바로 GraphQL를 사용해 본다면 어떻게 바뀔까? GraphQL로 보내는 요청과 응답은 아래와 같다.

요청(Request)

query {
  person(personId: 1) {
    imgae
    name
    nick_name
  }
}

 

응답(Response)

```javascript
{
  "data" : {
    "person" : {
      image: 'hosting.jpg',
      name: '정규현',
      nick_name: 'Jacob',
    }
  }
{
```

슈퍼쿨(Super Cool)하다. 쓸데없는 나머지 필드들이 없기 때문에 데이터를 받은 후 추가 가공에 대한 생각을 덜 수 있고, 필요한 데이터만 있기 때문에 심플하다. 만약 데이터가 많았다면, 응답 속도도 빨라질 수 있는 부분이다(많음에 대한 논의는 하지말자...).

Under Fetching (언더 페칭)

우린 열심히 여차저차 해서 간단한 유저 정보 화면을 REST한 방법으로 구현했다 하자. 근데 고객의 요구 사항이 추가되서 아까 화면에 정보를 받은 후에, 이 유저가 참여한 모든 프로젝트를 표시해 줘야 한다고 하자. 그럼 우린 또 다시 데이터를 요청해야 한다. 근데 그 프로젝트에 참여한 유저 정보도 불러야 한다면?
데이터는 점점 방대해 질 것이다. 이처럼 데이터를 요청하고 추가 데이터를 또 요청해야 하는 것을 언더페치(under fectch)라고 표현한다. GraphQL은 이마저도 원하는 데이터만 요청하여 해당 데이터만 받아온다.

REST 엔드포인트 관리

REST API를 설계해봤다면 알겠지만, 유연성이 정말 없다. 경우마다 엔드포인트를 새로 만들어야 한다. 그래서 수 많은 엔드포인트가 생기고 설계한 개발자라도 다 못 외울 것이다(아..마도?). 여기서 시간도 많이 든다. 대부분 백엔드 개발자와 프론트 개발자가 협업을 하기 때문에 프론트 개발자가 요청하면서 백엔드 개발자와 요구사항을 확인하고 긴 토의를 해야한다.

하지만, GraphQL을 사용하면 설계상 엔드포인트가 보통 한개이다. 단일 엔드포인트로 위와 같이 쿼리만 조정하여 필요한 데이터를 받는다. 의사소통 비용자체가 줄어든다!

 

GraphQL 클라이언트

사실 GraphQL은 그냥 명세에 지나지 않는다. 명세가 뭔지 모르겠다면 자바스크립트의 ECMAScript라고 생각하면 된다. 몇 가지 주의 사항을 제외 하고는 GraphQL로 개발하는 개발자가 정할 수 있다. 그래서 등장한 것이 GraphQL 클라이언트이다. 몇 가지 선택을 강제하게 함으로써 개발자가 빠르게 작업할 수 있는 작업 환경을 만들고 애플리케이션의 성능과 효율을 끌어 올려주는 것이다. 네트워크 요청, 데이터 캐싱, 사용자 화면에 데이터 주입 등을 담당하며, 제일 유명한 클라이언트로는 RelayApollo(아폴로) 가 있다.

Relay는 페이스북이 만든 클라이언트이고 React와 React Native (당연한 이야기 인가?;;)에서 함께 사용할 수 있다. 실제로 페이스북, 깃허브, 트위치 등에서 사용 중에 있다.

Apollo는 Meteor라는 곳에서 만들었으며, 좀 더 복합적인 GraphQL 툴을 제공한다. 모든 주요 프론트엔드 개발 플랫폼에서 사용할 수 있으며, 프레임 워크에 종속적이지 않다. 또한 유용한 서비스 및 모터터링 툴을 제공하며, 실제로 에어비앤비, 뉴욕타임스, 티멧마스터 같은 회사에서 사용하고 있다.

이처럼 이미 유명 회사에서 사용하고 검증되었으며 실제로 GraphQL 명세가 이미 안정적인 상태(표준)이다.

 

참고 자료

  • Learing GraphQL by Eve Porello and Alex Banks(O'Reilly). Copyright 2018 Moon Highway, LLC, 978-1-492-03071
  • https://graphql.org/
반응형