
GraphQL은 Facebook(현 Meta)에서 만든 API를 위한 쿼리 언어이자 서버 사이드 런타임이다. 특이하게도 쿼리 언어이지만 SQL이 아니라 REST와 비교되곤 한다. 왜 그런걸까? 이는 SQL이 데이터베이스에 저장된 데이터를 가져올 목적으로 사용되는 것에 비해, GraphQL은 클라이언트가 서버로부터 데이터를 가져올 목적으로 사용되기 때문이다.
메타는 불필요한 네트워크 트래픽을 줄이기 위해 GraphQL을 개발했다고 한다. 기존의 REST API 방식은 필요한 것에 비해 많은(오버페칭), 아니면 적은(언더페칭) 데이터를 주기 때문에 문제가 발생했다는 것이다. 예를 들어 상품명에 대한 데이터만 필요한데 /product 엔드포인트에 접근하면 상품명 뿐만 아니라 가격, 할인 정보, 입고일 등 사용하지 않을 데이터가 같이 딸려오거나, 반대로 상품명과 주문자에 대한 정보가 필요한데 그 두개를 같이 내려주는 API가 없어서 /product 와 /member를 각각 요청해서 정보를 얻는다거나 하는 식으로 말이다.
이런 문제에 대해 "GraphQL은 필요한 정보만 얻을 수 있다!" 라고 해서 궁금했다. 클라이언트가 "A만 내려주세요" 요청하면 서버는 A만 전달해준다는 것이다. 이게 어떻게 가능할까? 궁금해서 관련 내용을 조사하고, 그 중에서 REST와 GraphQL을 비교하는 괜찮은 자료가 있어서 해당 내용을 토대로 차이에 대해 쉽게 이해할 수 있었다.
GraphQL vs REST: Which is Better for APIs?
이하의 글은 영상의 내용과 함께 추가로 정리한 내용이다.
(/products/baseball을 보내자 REST는 눈을 빛내기 시작했다.)
REST는 말이 많은 친구다. 나는 야구공의 가격에 대해서 물어봤는데, 야구공의 재질부터 제조사, 심지어 야구공의 실밥 갯수까지 알려준다. 지금의 내겐 불필요한 정보다. 하지만 이 친구는 내가 나중에 다시 물어봐도 자기가 알고 있는 야구공의 모든 것에 대해 내게 알려줄 거다.
GraphQL은 말수가 적은 친구다. 내가 야구공의 가격에 대해서 물어보면 딱 그것만 알려준다. 5,000원. 그렇다고 이 친구가 내가 물어보면 안 알려주는 건 아니다. 그저 내가 물어본 것만 알려줄 뿐이다. 야구공 실밥 갯수는 몇개야? 108개.
REST나 GraphQL 모두 API를 위한 것이다. 둘은 HTTP를 통해 통신하고, JSON으로 데이터를 내려줄 수 있는 등, 비슷한 점이 있다. 하지만 보여지는 차이점이 더 크다.
REST는 자원을 URI와 HTTP 메서드로 조작하는 스타일이다. REST에서는 필요한 정보에 따라 엔드포인트가 나뉜다. 내가 회원 정보가 필요할 때는 /users/12345, 상품 정보가 필요할 때는 /products/abcde 등, 어떤 정보가 필요한지에 따라 요청하는 URI가 달라진다. 반면 GraphQL은 단 하나의 엔드포인트만 가진다. 하나의 엔드포인트에 어떤 쿼리를 보내느냐에 따라 다른 데이터를 받는 것이다.
CRUD는 어떻게 하는가? REST에서는 HTTP Method를 이용해서 CRUD를 적용한다. 같은 /posts URI 여도 POST 방식으로 보냈다면 게시글 생성을, GET 이라면 게시글 목록을 반환한다.
그렇다면 GraphQL은 어떻게 이런 처리를 할 수 있나? GraphQL에서는 정보를 얻을 때(Read) Query를 사용하고, 그 외 Create, Update, Delete에 대해서는 Mutation을 사용한다.
그렇다면 GraphQL은 내가 요청하면 어떤 것이든 바로 내려줄 수 있는 것인가? 아니다. GraphQL에서 원하는 데이터를 받기 위해선, 해당 데이터가 스키마로 정의되어야 한다.
스키마란 타입 시스템 기반의 계약이라 볼 수 있다. 어떤 데이터를 요청할 수 있고, 어떤 형태로 받을 수 있는지 데이터의 구조와 타입을 정의한다. 이를 통해 우리는 서버에서 어떤 데이터를 받을 수 있는지 확인할 수 있다.
| 구분 | REST | GraphQL | 
|---|---|---|
| 요청구조 | 여러 엔드포인트 | 하나의 엔드포인트 | 
| 데이터 응답 | 리소스 전체 반환 | 필요한 필드만 반환 | 
| 데이터 요청 | 관련 데이터는 여러 요청 필요 | 복잡한 쿼리로 한 번으로 가능 | 
| 캐싱 | HTTP 캐싱 지원 용이 | 별도의 라이브러리 필요 (Apollo 등) | 
| 학습 난이도 | 쉬움(많이 사용됨) | 학습 곡선 있음 | 
| 사용 사례 | 단순 CRUD 중심 | 복잡·중첩 데이터 요청 | 
아니다. 장점만 있는 기술은 없다. REST와 GraphQL은 상호 보완적인 기술이다. REST로 구현하는게 더 편리할 때가 있으며, 반대로 GraphQL로 구현하는게 더 효율적인 상황이 있을 수도 있다. REST는 단순 CRUD와 캐싱이 중요한 경우에 여전히 강력하고, GraphQL은 클라이언트가 여러 데이터 소스를 한 번에 불러와야 할 때 빛을 발한다. 따라서 둘 중 어느 하나를 선택한다기보단, 어떤 기능을 구현하느냐에 따라 선택하는 것이 핵심이다. GraphQL을 사용한다고 해서 REST 방식을 사용하지 못하는 것이 아니기에, 상황에 따라 적절한 방식을 사용하는 것이 중요하다.
하지만 이렇게 영상을 보고 정리해도, 직접 겪어봐야 머리에 남는다. 그래서 GraphQL과 React Native, 그리고 monorepo를 공부하기 위한 토이 프로젝트를 만들었다. 토이 프로젝트에 여러가지 서비스를 적용해보면서, 괜찮다 싶으면 이 블로그에도 하나하나 적용해볼 예정이다.