가볍게 RESTful API가 익숙하신 분들에게 GraphQL에대해 설명해드리는 글을 하나 작성해보려고 합니다.
GraphQL이란 무엇인가?
GraphQL은 RESTful API와 비교했을때 Response를 효율적으로 받아오는데에 공을 많이 들인 아키텍쳐입니다. RESTful API의 경우 효율적으로 설계할경우 일반적으로 한 페이지를 디스플레이하는데 필요한 데이터를 가져올때 여러번의 반복적인 서버-클라이언트 요청이 있어야하지만 GraphQL은 그런 불필요한 오버헤드를 말끔히 해결해주는 차세대 아키텍쳐라고도 볼 수 있겠습니다. 간단한 예를들어 만일 책을 파는 이커머스 웹사이트를 제작한다고 한다면 아래와 비슷한 객체들이 최소한으로 필요할 것입니다.
Book Table
id | name | createdAt |
---|---|---|
1 | Atomic Habbit | 2011-10-05T14:48:00.000Z |
Author Table
id | name | createdAt |
---|---|---|
1 | James Clear | 2011-10-05T14:48:00.000Z |
Publisher Table
id | name | createdAt |
---|---|---|
1 | Avery | 2011-10-05T14:48:00.000Z |
Reviewer Table
id | name | createdAt |
---|---|---|
1 | New York Times | 2011-10-05T14:48:00.000Z |
위와같이 책, 작가, 출판사, 리뷰업체등을 테이블로 만들고 Book 테이블과 나머지 세개의 테이블이 다대다 형식으로 FK를 통해 연결되어 있어야 합니다. 중복을 죽기보다 싫어하는 타입이라면 아래와같은 여러 네트워크 요청을 해야하는 일이 벌어지죠
책 리스팅 해오기
GET /books?limit=10
책마다 작가 가져오기
GET /author?bookId=1
책마다 출판사 가져오기
GET /publisher?bookId=1
책마다 리뷰어 가져오기
GET /reviewer?bookId=1
한 API에 모두 쓸어 담을수도 있긴 하겠지만 그럴경우 Author, Publisher, Reviewer를 따로 책 리스팅과 관련없이 가져오고싶을 경우 중복의 느낌이 상당합니다. 결과적으로 RESTful API를 사용하면 책을 리스팅해오는 페이지에서 책을 가져오는 요청 외에 각 책마다 3개의 요청을 추가적으로 하게되고 상당한 네트워크 오버헤드를 발생시킵니다.
하지만 GraphQL은 이런 네트워크 오버헤드를 완벽히 보완한 아키텍쳐입니다. 위 요청을 GraphQL의 형태로 작성한다면 아래와같은 요청이 됩니다.
query getBooks{
id
author{
id
createdAt
}
publisher{
id
createdAt
}
reviewer{
id
createdAt
}
createdAt
}
위 한개의 요청을 POST 요청으로 GraphQL서버에 보내서 한번에 책들과 관련된 모든 연관된 객체들을 이미 작업된 형태로 클라이언트에서 받을 수 있습니다. 더 나아가 서버에서는 모든 엔드포인트마다 객체끼리 테이블 JOIN을 반복적으로 해줘야하는 RESTful API와 다르게 한번만 각 객체들의 관계만 연결을 해주면 위 예제처럼 연관성이 있는 객체들을 가져올때 자동적으로 GraphQL에서 매핑을 해줍니다. 예를들어 이미 book 과 author의 관계, book과 publisher의 관계, book과 reviewer의 관계가 이미 getBooks 쿼리를 제작할때 매핑을 해놨기때문에 다음에 addBook이라는 새로운 요청을 만들때는 해당 작업을 반복해서 해줄 필요가 없습니다. 결과적으로 코드도 깔끔해지고 효율적이여집니다.
추가적으로 RESTful API의 경우 서버가 지정한 형태의 response만 받아볼 수가 있습니다. 하지만 GraphQL에서는 response의 형태를 상당히 자유롭게 가져갈 수 있습니다. 예를들어 위 쿼리에서 책의 createdAt이 필요가 없고 리뷰어는 전혀 가져올 필요가 없다하면 아래와같이 쿼리를 변경하면 됩니다.
query getBooks {
id
author {
id
createdAt
}
publisher {
id
createdAt
}
}
서버에서는 그 어떤 추가적 코드도 작성할 필요가 없습니다.
결과적으로 GraphQL은 RESTful API 아키텍쳐와 비교했을경우 네트워크 오버헤드를 많이 줄여주고 서버 작업시에 중복 작업을 많이 줄여줍니다. 이외에도 각 언어별/라이브러리별 GraphQL 클라이언트마다 캐싱 지원, Optimistic Response등 상당히 많은 유용한 기능들이 탑재되어 있으니 간단한 프로젝트라도 GraphQL을 사용해보시는건 좋은 경험이 될것같습니다.