GraphQL은 한 번의 API 호출로 여러 소스에서 데이터를 가져올 수 있는 오픈 소스 API 쿼리 언어입니다. 또한 기존 데이터를 사용해 쿼리를 처리하는 서버 측 런타임 역할도 합니다. GraphQL은 완전한 API 데이터 명세를 제공하면서도 클라이언트가 요청한 데이터만 전달하는 것을 우선시하며, API를 더 쉽게 확장하고 발전시킬 수 있도록 지원합니다.

GraphQL 이해하기

GraphQL은 유연성, 속도, 그리고 개발자를 염두에 두고 설계되었습니다. 개발자는 GraphQL을 사용해 원하는 방식으로 API를 구축한 다음, GraphQL 사양을 통해 해당 API가 클라이언트에서 제대로 작동하도록 보장할 수 있습니다.

GraphQL 쿼리의 핵심 개념 중 하나는 반환되는 데이터를 예측할 수 있다는 것입니다. 불필요한 코드 문자열 대신 요청한 내용만 정확히 반환됩니다. 이러한 선언적 데이터 가져오기 방식은 대역폭이 제한된 모바일 기기에서 특히 유용합니다. 또한 GraphQL을 사용하는 앱은 서버가 아닌 앱 자체에서 요청하고 수신할 데이터를 제어하므로 안정적이고 빠릅니다. 한 번의 요청으로 여러 항목을 동시에 반환받을 수 있어 네트워크 연결이 느린 환경에서도 빠르게 작동합니다.

GraphQL의 데이터 단순화를 기반으로 API는 엔드포인트가 아닌 유형과 필드별로 구성됩니다. 즉, 단일 엔드포인트에서 모든 데이터에 액세스할 수 있으므로 앱은 필요한 데이터만 요청할 수 있습니다. 운영 복잡성을 줄여 주는 GraphQL은 간소화된 API 연결 솔루션의 워크플로에 적합합니다.

간략한 역사

2012년, Meta(당시 Facebook)는 Facebook 모바일 애플리케이션에 사용할 수 있을 만큼 강력한 데이터 가져오기 API가 필요했습니다. Lee Byron의 주도로 Facebook은 제품 디자이너와 개발자의 관점에서 데이터 가져오기를 간소화하기 위한 방법으로 GraphQL을 개발했습니다. GraphQL은 처음에는 Facebook 내부에서 사용되다가 2015년에 공개 및 오픈 소스화되었습니다. 다른 많은 오픈 소스 프로젝트의 전례에 따라, 2019년 GraphQL 프로젝트는 독립적인 GraphQL Foundation으로 이전했으며, Linux Foundation이 이를 주관합니다.

GraphQL은 REST 아키텍처의 대안으로 설계되었습니다. 표준 REST API에서는 여러 URL의 정보를 각각 별도의 HTTP GET 요청을 통해 불러와야 합니다. GraphQL API에서는 단일 POST 요청으로 모든 데이터를 가져옵니다. REST와 GraphQL 모두 JSON 형식의 응답을 반환하지만, GraphQL은 데이터를 간소화하고 통합하는 데 중점을 둡니다.

GraphQL은 어떻게 작동하나요?

GraphQL은 세분화된 데이터 요청을 지원하며, 전송되는 정보를 클라이언트가 더욱 세밀하게 제어할 수 있도록 합니다. 클라이언트가 GraphQL 쿼리를 POST 요청 형식으로 보내면 서버는 JSON 형식의 응답을 반환합니다. GraphQL은 특정 애플리케이션 아키텍처를 요구하지 않으며, 통합 개발 환경(IDE)을 비롯한 다양한 환경에 배포할 수 있습니다. 또한 기존 API 관리 도구와 함께 사용하거나 기존 REST API 위에 적용할 수 있습니다.

GraphQL의 주요 용어는 다음과 같습니다:

  • 스키마 – API 개발자가 클라이언트가 쿼리할 수 있는 데이터를 보여 주기 위해 생성합니다. 스키마는 클라이언트가 요청할 수 있는 항목과 객체의 특성을 나타내는 필드를 정의하는 객체 유형으로 구성됩니다.
  • 쿼리 – 쿼리는 스키마를 기준으로 유효성 검사를 거친 후 실행됩니다. GraphQL은 객체 유형을 정의하지 않으면 쿼리를 실행할 수 없습니다.
  • 리졸버 – 각 스키마 필드에 연결된 리졸버 함수는 API 실행 시 값을 생성하기 위해 호출됩니다. 리졸버는 GraphQL의 핵심 아키텍처 구성 요소입니다.

GraphQL의 고유한 특징 중 하나는 응답이 쿼리의 구조(쿼리 자체는 스키마에 의해 정의됨)를 그대로 반영한다는 점입니다. 따라서 서버 응답의 형식을 완전히 예측할 수 있으므로 클라이언트에서 응답을 더 쉽게 파싱할 수 있습니다.

설계

GraphQL의 계층적 특성은 객체 간의 관계를 따르므로 계층형 사용자 인터페이스에 적합합니다. 또한 강력한 타입 시스템을 갖추고 있어 각 쿼리 수준이 특정 타입과 일치합니다. 이러한 타입은 다시 필드 집합을 정의합니다. 이는 쿼리를 완료하기 전에 구체적인 오류 메시지를 표시하는 SQL과 유사합니다.

리졸버를 데이터 소스에 연결하기

리졸버는 GraphQL 필드, 엣지, 뮤테이션, 쿼리 및 구독을 데이터 소스(및 마이크로서비스)에 연결하는 핵심 아키텍처 모듈입니다.

이 GraphQL 자습서에서 AWS 데이터 소스용 리졸버를 구축하는 방법을 알아볼 수 있습니다.

가져올 항목 지정

GraphQL 쿼리의 고유한 특징 중 하나는 응답이 쿼리의 구조를 그대로 반영한다는 점입니다. 쿼리에서 반환되는 데이터가 API 요청의 구조와 일치한다는 것을 알 수 있으므로 결과를 예측할 수 있습니다. 반환되는 데이터의 구조가 클라이언트 쿼리를 따르면 서버가 단순해집니다.

GraphQL의 장점

GraphQL의 주요 이점 중 하나는 REST에서는 제공되지 않는 기능을 확장 기능을 통해 사용할 수 있다는 점입니다. 그 밖의 GraphQL 장점은 다음과 같습니다.

단일 진실 공급원 설정

GraphQL 스키마는 GraphQL 애플리케이션에서 모든 데이터를 기술하는 중심 위치를 제공하여 단일 진실 공급원 역할을 합니다. GraphQL 스키마는 일반적으로 서버에서 정의되지만, 클라이언트도 스키마를 기반으로 데이터를 조회하고 쓸 수 있습니다.

오버페칭 방지

REST 아키텍처에서는 오버페칭이 금세 문제가 될 수 있습니다. 애플리케이션(백엔드)이 각 리소스에서 사용할 수 있는 데이터를 정의하고, 클라이언트(프런트엔드)가 단 하나의 요소만 필요로 하더라도 응답에 모든 데이터를 반환하기 때문입니다. GraphQL 호출은 한 번의 요청으로 이루어지며, 오버페칭 없이 클라이언트가 요청한 데이터를 제공합니다.

클라이언트와 서버 간 통신 개선

데이터 유형이 엄격하게 정의되어 있으므로 GraphQL에서는 REST보다 클라이언트와 서버 간의 통신이 더 명확합니다. 또한 이러한 기본 구조 덕분에 GraphQL 서버를 호출하는 데 복잡한 클라이언트가 필요하지 않습니다. 자세한 내용과 실제 코드 예시는 GraphQL 공식 페이지에서 클라이언트와 서버에 관한 내용을 확인하세요.

페더레이션을 통한 확장성

API Federation은 일련의 설계 원칙과 도구를 통해 경계가 명확한 컨텍스트 내의 서비스를 사용자에게 일관된 API로 제공하는 동시에, 해당 컨텍스트 내의 서비스가 제약 없이 발전할 수 있도록 합니다. GraphQL은 기존 쿼리를 중단시키지 않으면서 전체 API를 페더레이션하고 발전시킬 수 있는 방법을 제공하므로 확장성이 뛰어납니다. 이러한 확장성은 많은 기업이 GraphQL을 사용하는 이유 중 하나입니다.

인트로스펙션

GraphQL의 인트로스펙션 특성을 활용하면 GraphQL API에서 GraphQL 스키마를 가져올 수 있습니다. 클라이언트는 사용 가능한 데이터 유형 목록도 요청할 수 있으므로 문서를 자동으로 생성하거나 여러 마이크로서비스의 스키마를 테스트 또는 가져오는 데 적합합니다.

GraphQL의 단점

GraphQL을 도입해야 할 이유는 많지만, 알아두어야 할 몇 가지 단점도 있습니다. 예를 들어 모든 기능이 기본으로 제공되는 것은 아니므로 다른 사람의 API를 사용하려면 별도의 라이브러리가 필요합니다. 또한 전반적으로 GraphQL은 REST보다 더 많은 도구 지원이 필요합니다.

REST와 비교했을 때 GraphQL의 단점은 다음과 같습니다.

학습 곡선

REST API에 익숙한 개발자에게는 GraphQL의 학습 곡선이 더 가파를 수 있습니다. 또한 워크플로가 달라질 수 있습니다. GraphQL을 사용하는 API 팀은 유지 관리가 용이한 GraphQL 스키마도 작성해야 합니다. 하지만 처음부터 새로 시작한다면 요청과 응답의 구조가 동일하기 때문에 GraphQL을 쉽게 배우고 사용할 수 있습니다.

고유한 API 관리 전략

GraphQL에는 새로운 API 관리 전략이 필요할 수 있는 반면, REST API는 기존 API 관리 모델에 잘 부합하는 경향이 있습니다. 새로운 API 관리 전략을 추가하면 전체 비용이 증가할 수 있으므로, 이 점을 중요하게 고려해야 합니다.

복잡한 캐싱

GraphQL의 캐싱은 일반적으로 HTTP 메서드(GET, POST, PUT 또는 DELETE)를 사용하는 REST의 캐싱보다 덜 직관적입니다. 표준 GraphQL 요청은 POST 방식이므로 HTTP 수준에서 캐시할 수 없습니다. 또한 GraphQL은 단일 엔드포인트를 사용하기 때문에 캐싱이 복잡해질 수 있습니다. 즉, 하나의 엔드포인트 URL에서 캐시할 수 없는 다양한 응답이 생성됩니다(데이터를 가져오는 데는 유리하지만 캐싱에는 불리함). 그 결과 서버 개발자는 각 쿼리가 동일한 객체 내에서 작동하더라도 쿼리를 서로 다르게 처리하게 됩니다. 그렇지만 많은 GraphQL 라이브러리는 기본적으로 캐싱 메커니즘을 제공합니다.