Read GraphQL docs
Exploring the concept of GraphQL and its benefits
July 29, 2024
GraphQL을 스터디하게 된 배경
제품을 만들기 위해서 많은 기능이 필요 하였고 그에 따라 많은 API를 연동하여 개발하였는데 시간이 지나 자연스럽게 API가 추가되거나 변경되는 일들이 많아지게 되었습니다. 이것은 결국 API 스펙이 추가되거나 변경되는 일이 발생하는 것을 의미하였고 그에 따라 클라이언트가 다루어야 할 엔드 포인트에 대한 인터페이스를 유지보수하는 것은 쉽지 않았습니다. 더군다나 API 스펙을 문서로 정리하는 것은 처음엔 쉬울지 몰라도 지속적으로 관리하는 것은 절대 쉬운 일이 아니였습니다.
사이드 프로젝트에 이러한 문제들을 GraphQL을 도입하므로써 해결 할 수 있지 않을까 생각하여 문서들을 읽고 가장 인상 깊었던 부분들을 요약 해보았습니다.
GraphQL 이란
클라이언트에서 이해 할 수 있는 언어입니다. 비슷한 예로 SQL이 있는데 질의를 작성하는 시점에 정확히 어떤 데이터를 반환 하는지 이해 할 수 있음을 뜻합니다. 그리고 GraphQL은 라이브러리가 아닌 스펙을 정의한 것입니다. 정의된 스펙에 따라 언어에 맞게 개발 할 수 있습니다. GraphQL 방식으로 개발하려면 GraphQL 클라이언트와 GraphQL 서버가 필요합니다. GraphQL 서버는 언어마다 라이브러리가 많이 존재하고 클라이언트로서는 제일 유명한 것은 Relay와 Apollo가 있습니다.
Relay VS Apollo
Relay는 메타에서 개발한 라이브러리로 GraphQL을 설계하고 서비스에 적극적으로 도입한 회사답게 자신들의 철학에 맞게 개발되어 있습니다. 제일 상위에 쿼리가 존재하고 해당 쿼리를 프레그먼트로 슬라이스하여 각 컴포넌트에서 사용하는 방식입니다. 이러한 구조는 스케일링에 적합한 구조입니다. 서비스가 커지더라도 슬라이스된 프레그먼트를 통해 캐시 히트를 극대화 시킵니다. 다만 컴포넌트에 하나의 프레그먼트를 대응하여 선언하는 방식을 취하기 때문에 컨벤션이 까다롭고 Relay만의 디렉티브가 존재하여 러닝커브가 적지 않습니다. 그리고 SSR을 공식적으로 라이브러리에서 지원하지 않기 때문에 별도의 라우터 작업이 필요합니다.
Apollo는 Relay와 대부분의 기능을 비슷하게 제공하지만 특정 컨벤션에 고정되지 않을 수 있도록 유연성을 제공합니다. SSR 또한 라이브러리 레벨에서 공식 지원하고 있습니다.
이러한 대략적인 특징을 가지고 있으며 어떤 것을 선택 할 지는 제품의 스펙 내에서 SSR의 필요성에 따라 결정되리라 생각됩니다.
GraphQL을 도입하면 좋은 점
엔드포인트를 하나로 통합 할 수 있으며, 클라이언트에서 요청하는 시점에 어떤 데이터를 가져오는지 이해 할 수 있습니다. Rest API를 사용하다보면 흔히 마주하는 언더패칭(데이터를 만들기 위해 여러 API를 호출)과 오버패칭(API 응답에 불필요한 데이터까지 포함)을 없앨 수 있습니다. 또한 GraphQL 서버에서 제공하는 Playground 사이트를 통해 별도의 문서 없이도 데이터 인터페이스를 확인 할 수 있습니다. (별도의 코드 작성을 하지 않아도 됩니다) 그리고 GraphQL 서버가 중간에서 백엔드 API를 통합하여 제공하므로 시스템 마이그레이션에 유리합니다. 예를 들어 인터페이스 내에서 데이터가 서로 다른 출처를 가진다고 하더라도 클라이언트는 해당 부분에서 신경 쓸 필요가 없습니다.
하나의 GraphQL 데이터가 하나의 내부 API를 통해 제공하다가 분리된 여러개의 내부 API를 조합하여 제공 할 수 있으며, 이 말은 백엔드에서 시스템의 유연성이 생김을 의미합니다. 별도의 엔드 포인트를 추가하거나 변경하지 않아도 되며 클라이언트가 요청하는 쿼리에 대해서 각가의 속성 별로 데이터를 제공하면 되기 때문입니다.
GraphQL을 도입하면서 조심해야 할 점
GraphQL은 한번 인터페이스를 설계하면 되돌리기가 쉽지 않습니다. 그래서 공식문서에도 시스템의 모든 데이터를 한번에 마이그레이션하는 것을 추천하지 않고 점진적인 도입을 통해 실수를 줄여나가는 것을 권장하고 있습니다. GraphQL 서버가 백엔드 서버 앞단에 존재하여 클라이언트의 요청을 받는 역활을 하게 되므로 인프라를 잘 관리해야합니다. 실제로 어떤 서비스에서 GraphQL을 사용하는데 많은 요청이 한번에 밀려 GraphQL 서버 오류가 클라이언트에 그대로 노출된 적이 있습니다.