[GraphQL] 특징 그리고 장점과 단점

GraphQL에 대해서 어느정도 알고있지만 정리가 필요할 것 같아 잘 정리된 영문으로된 글을 읽으면서 간단하게 정리해보려고 합니다. (읽으면서 알게된 내용을 적어서 순서가 뒤죽박죽입니다 😅)

GraphQL?

최근에도 많이 사용되는 REST(Representational State Transfer) API design은 클라이언트에게 CRUD API를 제공하기 간단했습니다. 하지만 최근부터 복잡한 데이터를 요구하는 클라이언트, 다양한 종류의 클라이언트(mobile, desktop, TV 등등..)가 증가하면서 한 API로 모든 클라이언트를 만족시키는 건 어려운 일이었습니다. 또 성장하고 있는 사업 분야에서 다양한 비즈니스적인 요구들을 반양하기에 REST API design은 클라이언트/서버 모두 업데이트해야 하기 때문에 기능 제공이 느려질 수 밖에 없었습니다.

GraphQL은 클라이언트에서 어떤 데이터를 조회할지 명시할 수 있게 해주는 언어라고 할 수 있습니다. 2012년에 Facebook에서 만들어졌는데, 명확한 data-fetching을 통해서 네트워크 사용량을 줄이고자 하는 목적으로 만들어졌습니다. 처음에는 자바스크립트에서만 구현되었지만 최근에는 여러 메이저한 언어(Python, Java 등)에서도 구현되어 널리 사용되고 있습니다.

GrapghQL 서버에서는 SDL(Schema Definition Language)로 Schema를 작성하고 클라이언트에서는 해당 Schema에서 얻고자 하는 데이터를 quering합니다. 서버에서는 Schema에 작성된 resolver로 데이터를 가져와 결과를 내려줍니다. 클라이언트에서도 데이터 구조를 명시하여 query를 날리기 때문에 응답 데이터의 구조를 클라이언트 코드상에서 쉽게 파악할 수 있고, 서버로부터 원하는 데이터만 가져올 수 있기 때문에 자원에 대한 over-fetching(클라이언트에서 필요하지 않은 데이터들도 함께 내려주는 문제, REST는 서버에서 정의한 데이터들을 응답해주기 때문에 발생하는 문제)이 발생하지 않습니다. 또 원하는 데이터를 한 번에 다 가져올 수 있어 네트워크 요청수를 줄일 수 있습니다.

GraphQL에는 Query(데이터 읽기), Mutation(데이터 쓰기), Subscription(실시간 데이터 불러오기) 이렇게 3가지의 작업(operation)이 있습니다.

장점

  • 요즘 대세인 마이크로서비스에서 사용하기 좋습니다.

    • 중앙 GraphQL 리졸버 서버에 모든 서비스(레거시 시스템/마이크로서비스의 컴포넌트들/외부 API 등)의 Schema를 작성하여 사용하게 되면 하나의 서버로 여러 서비스들로부터 데이터를 가져올 수 있어 복잡한 구조를 단순화시킬 수 있고 클라어인트 입장에서도 여러 주소를 알 필요 없이 중앙 GraphQL 서버 주소만 알면 되기 때문에 개발에 있어서도 편리합니다.
  • 한 번의 요청으로 필요한 데이터를 모두 가져올 수 있습니다. (네트워크 비용 절감)

    • 위에서도 얘기한 내용이지만, 한 번더 얘기하자면 REST와는 다르게 필요한 리소스를 하나의 요청으로 전부 가져올 수 있다는 장점이 있습니다. REST의 특징은 리소스별로 엔드포인트를 다르게 가져가는 것인데 이러한 특징이 과거에는 URL을 보고서도 어떤 데이터를 가져올지 알 수 있는 장점이었지만, 복잡하고 다양한 데이터를 다뤄야 하는 요즘 시대에는 단점으로 작용할 때도 있습니다.
  • 유효한 Query인지 자동으로 검증해줍니다.

    • 올바른 형태의 데이터로 요청했는지 파악하기 위해서 실제로 요청을 날려봐야하는 REST와는 달리 GraphQL에서는 별도의 요청없이도 검증할 수 있기 때문에 별도의 검증 코드 없이 개발자는 리졸버만 작성하면됩니다.. 또 코드를 수정하지 않고 새로운 필드를 추가해볼 수 있는 GraphQL IDE도 제공하고 있습니다.
  • API 스펙 문서화 기능을 제공합니다.

    • 문서를 이쁘게 보여주는 툴들도 존재하니 골라서 사용하면 됩니다.
  • 여러 Query에서 반복되어 사용되는 필드들을 공유하여 사용할 수 있습니다.

    • GraphQL에서는 Fragments(프래그먼트)라고 불리는 재사용성이 높은 코드를 제공하기 위한 기능이 있습니다.
  • Pub/Sub 구조를 지원합니다.

    • 실시간 데이터를 Pub/Sub 구조로 이벤트 발생 시 클라이언트에게 전달하는 기능이 구현되어 있습니다. ajax polling과는 다르게 이벤트가 발생될 때만 보내주기 때문에 효율적이지만 서버의 리소스를 게속해서 잡고 있기 때문에 주의해야할 거 같습니다.
  • 빠른 프로토타이핑이 가능합니다.

    • CRUD 작업을 구현하기 위해서 여러 API를 만들어야 하는 REST와는 다르게 하나의 엔드포인트로 모든 작업을 구현할 수 있습니다.

단점

  • 한번에 너무 깊은 데이터를 요청하면 성능 문제가 발생합니다.

    • 클라이언트가 원하는 데이터를 한번에 가져가는 것이 장점으로 뽑히기도 하지만 너무 깊은 구조의 데이터를 요청하면 성능 이슈가 발생할 수 있습니다. 최대 쿼리 깊이, 쿼리 복잡성 가중치, 재귀 방지, 영구 쿼리드을 이용하여 성능을 개선할 수 있습니다.
  • 규모가 작은 서비스를 구현할 때는 다소 과한면이 있습니다.
  • 캐싱 구현을 위한 별도의 로직들을 필요로 합니다.

    • URL, HTTP method 등을 식별자로 이용하여 캐싱을 구현할 수 있는 REST와는 다르게 캐싱 기능을 구현하기 위해서는 고유한 ID를 제공하거나 Dataloader와 같은 유틸 라이브러릴 이용하여 캐싱 기능을 구현해야 합니다.
  • 파일 업로드 기능을 기본으로 제공하지는 않습니다.

    • 파일 업로드를 하기위해 별도의 라이브러리를 사용하거나, 이부분만 REST를 사용하는 방식으로 해야할 거 같습니다.
  • 러닝 커브가 높습니다.

    • REST를 배울 때보다 알아야할 게 훨씬 많습니다. 팀의 상황과 러닝 커브를 극복해야할 만큼의 필요성이 있을 때만 사용하는 게 좋습니다. 효율이 비슷한데 굳이 복잡한 도구를 쓸 필요는 없으니..

참고하면 좋습니닷!


Written by@EHX
Software Developer, Back-End Engineer

GitHubFacebook