GraphQL: API 소비자에 대한 일관된 접근방식 수립
David Feuer
Senior Product Manager
* 본 아티클의 원문은 2021년 4월 2일 Google Cloud 블로그(영문)에 게재되었습니다.
개발자들은 애플리케이션 프로그래밍 인터페이스(API)를 사용해 새 모바일 또는 웹 앱의 데이터와 기능을 조합합니다. 하지만 API와 상호작용 시 개발자들이 가장 많이 사용하는 2가지 옵션은 REST와 GraphQL입니다.
이 문서에서는 두 접근방식을 비교하고 GraphQL API 소비자를 위한 보다 일관된 경험을 구축하는 데 적용할 수 있는 REST API 권장사항을 소개합니다. 두 접근방식은 우열을 가릴 수 없으며 동일한 프로젝트가 아니라면 같은 팀에서 둘 다 사용할 수 있습니다. 프로젝트에 수반되는 API 유형에 상관없이 일관된 경험은 개발자가 더 많은 작업을 빠르게 수행하는 데 도움이 됩니다.
REST 및 GraphQL 비교
REST는 API가 준수하는 소프트웨어 아키텍처 스타일로, 개발자가 사용하면 표준적인 방법으로 서비스와 상호작용할 수 있습니다. GraphQL은 API의 쿼리 언어이자 해당 쿼리를 처리하는 런타임입니다. REST와 GraphQL은 리소스를 URL로 식별하고 이를 통해 앱이 데이터나 기능을 가져올 수 있다는 점에서 유사하지만 많은 차이점이 존재합니다.
- GraphQL은 단일 엔드포인트에서 데이터를 교환하는 반면 REST는 여러 엔드포인트와 관련될 때가 많습니다. GraphQL 리졸버는 필드의 데이터를 가져오는데 리졸버가 실패해도 나머지 쿼리에서 유용한 데이터를 가져와 반환할 수 있습니다. 상호작용 패러다임에는 다수의 REST 쿼리를 수행할 때 예상되는 상황이 반영되어 있습니다. 따라서 GraphQL 쿼리 하나가 여러 REST 쿼리를 대체하는 경우가 많습니다.
- GraphQL은 과도한 또는 부족한 데이터 가져오기, 즉 엔드포인트가 앱에 필요한 수준에 비해 너무 많거나 적은 정보로 호출에 응답하는 것을 방지합니다. REST API는 다양한 결정 수준으로 제공됩니다. 데이터를 더 가져오는 경우도 있고 덜 가져오는 경우도 있습니다. 다시 말해 직원 이름과 ID 번호만 필요한 상황에서 전체 직원 프로필을 가져오는 등 앱이 지나치게 많은 데이터를 수신할 수도 있습니다. 마찬가지로 수신되는 데이터가 너무 적어서 앱에서 API를 한 번이 아닌 여러 번 호출해야 할 수도 있습니다.
- REST는 HTTP 동사를 사용하며 페이로드 데이터 교환을 위해 일반적으로 JSON을 사용합니다. 하지만 GraphQL에서는 HTTP POST 동사가 가장 많이 사용되며 프로토콜 내에 다양한 쿼리 유형이 지정됩니다. 또한 GraphQL은 스키마 정의 언어(SDL)라고 부르는 커스텀 쿼리 형식도 사용합니다. 요청에 커스텀 쿼리 언어가 사용되더라도 JSON이 반환되어 클라이언트가 응답을 쉽게 활용할 수 있습니다. GraphQL 클라이언트 라이브러리는 ReactJS UI 프레임워크와 기본적으로 통합되며 다른 언어 및 패러다임에서도 사용할 수 있어 오늘날 많은 개발자들이 활용하고 있습니다.
- 개발자의 탐색 관점에 차이가 있습니다. 개발자는 REST API 작동 원리를 이해하기 위해 일반적으로 포털을 상점처럼 사용하며 API를 탐색하고 상호작용합니다. GraphQL에서 포털은 기본 제공되는 플레이그라운드이며 개발을 위한 공간 역할도 합니다. 포털은 통합 개발 환경으로서 개발자가 새로운 쿼리를 즉석에서 탐색할 수 있으며 탭 완성과 같은 기능이 지원됩니다. 문서도 다릅니다. REST는 일반적으로 OpenAPI 사양과 포털을 사용합니다. 몇몇 OpenAPI 확장 프로그램도 존재합니다. 예를 들어 Apigee SmartDocs는 OpenAPI 사양으로 양방향 문서를 만듭니다. GraphQL 개발자는 일반적으로 스키마 기반 양방향 문서(예: Graphiql)를 사용해 개발하고 GraphQL 엔드포인트와 상호작용합니다.
이러한 특성으로 인해 GraphQL이 점점 더 많은 사용 사례에 쓰이고 있지만 채택 시에 문제가 발생할 가능성도 있습니다. 상호 운용성과 내부 인프라 해체가 필요한 프로젝트의 경우 GraphQL은 상이한 여러 기존 시스템의 몇 가지 API를 만드는 데 유용한 도구입니다. 하지만 API 관리 플랫폼을 통해 REST API를 제공하여 내부 및 외부의 혁신을 촉진하는 기업에서 일반적으로 수립하는 셀프서비스 개발자 프로그램과 관련 성장 전략에도 활용할 수 있습니다.
이러한 프로그램은 API를 빌드한 팀 이외의 많은 사용자가 팀에서 의도하지 않은 여러 사용 사례에 이 API를 사용할 수 있다는 점에서 전통적인 인프라 중심의 API 프로젝트와 다릅니다. 일관적이고 안정적이며 직관적인 개발자 경험이 얼마나 중요한지 알 수 있는 대목이며 GraphQL을 채택하는 데 장애 요소로 작용하기도 합니다. REST API 그룹은 상대적으로 손쉽게 훑어볼 수 있고 작업 내용과 방식이 직관적으로 표현되지만 아직 GraphQL에 익숙하지 않은 사용자가 많습니다.
GraphQL에서 REST 기반 권장사항 사용
사용자는 작업에 가장 적합한 도구를 사용할 수 있어야 하며 이러한 도구에는 GraphQL과 REST가 모두 포함될 수 있습니다. GraphQL로 작업 생산성을 높이려면 Google에서 수년 간 개발자 프로그램을 구축하며 개발한 REST 기반 권장사항을 채택하는 것이 좋습니다.
API를 기업에서 애셋을 가져와 그 애셋의 가치를 높이기 위해 내부 직원, 파트너 또는 외부 고객 등의 개발자에게 맡길 수 있게 해주는 디지털 제품이라고 생각해 보세요. API는 디지털 제품이므로 개발자가 사용 방법을 이해하고 시장에 매력적인 경험을 선보이려면 일관된 경험이 필요합니다. 개발자가 겪는 불편은 API를 채택하고 디지털 기업의 성장 전략을 추진하는 데 큰 걸림돌이 되므로 REST와 마찬가지로 GraphQL에서도 일관성이 핵심입니다.
그래프를 복수형 명사로 정의된 데이터 중심 계층 구조로 취급
REST 아키텍처 스타일의 주요 원칙 중 하나는 인프라 복잡성을 합리화하는 일관적이고 간소화된 인터페이스를 만드는 것입니다. GET/listEmployeesByDepartment가 제대로 작성된 REST 쿼리라고 생각하는 사람은 없을 것입니다. 이는 자바 함수에 더 가깝게 보이는 스타일입니다. 올바른 형식의 REST 리소스에서는 GET /Employees, POST /Employees와 같이 복수형 명사를 사용합니다. REST API는 예측 가능한 기대에 안정적으로 부응함으로써 개발자가 리소스를 사용하고 새로운 경험을 구축하는 속도에 직접적인 영향을 미칩니다. 시간이 돈이라는 사실을 잊지 마세요.
GraphQL의 스키마는 그래프 계층 구조를 사용해 한 카탈로그에 포함된 도서의 제목 및 저자와 같은 항목 간 관계를 정의합니다. 근본적으로는 데이터 중심 계층 구조이지만 자바 함수 스타일의 기능 계층 구조로 취급되는 경우도 있으며 그로 인해 예측 가능하고, 직관적이며, 일관된 경험을 방해하여 불편을 초래할 수 있습니다.
올바른 형식의 GraphQL은 올바른 형식의 REST와 비슷해야 합니다. /Books에서 GET이 가능하다면 /Books에 POST도 가능하다고 가정해야 합니다. 데이터 기반 명사 대신 동사 기반 함수로 정의된 GET listBooksByGenre와 같은 자바 스타일의 구조와 비교해 보세요. 어떻게 해야 POST할 수 있을까요? /BooksByGenre, /Books, /listBooks 등에 해야 할까요? 알 수 없는 일입니다. 따라서 데이터 중심 접근방식을 취하고 그래프를 데이터 중심의 계층 구조로 취급하는 것이 좋습니다.
REST가 더 적합한 경우 GraphQL을 고집하지 않기
REST에서는 사용자가 특히 CQRS(Command Query Responsibility Segregation)와 같은 패턴을 사용할 때 여러 URL에서 데이터를 요청하고 제출하는 경우가 많습니다. CQRS는 마틴 파울러가 처음으로 식별한 설계 패턴으로 데이터를 읽는 모델과 데이터를 업데이트하는 모델을 구분합니다. 개발자들은 REST에서 종종 CQRS를 사용해 마이크로서비스 아키텍처의 여러 서비스에서 데이터를 가져옵니다.
GraphQL에서는 특히 데이터 유형이 매우 다양하거나 제출된 데이터가 지나치게 적을 경우 변형(GraphQL 개발자가 데이터를 제출하는 방식)이 급속도로 매우 복잡해집니다. 데이터 가져오기를 데이터 제출과 구분하는 CQRS와 유사한 스타일을 사용하는 것이 좋습니다. 이는 이미 REST 기반 API 레이어를 갖춘 대기업에 특히 유용할 수 있습니다. GraphQL은 API 관리 레이어에 더하거나 이를 대신하는 형태로 데이터를 가져올 수 있지만 여전히 기존 REST API를 통해 데이터를 제출할 수 있습니다. 즉, REST가 적합할 때 개발자가 GraphQL을 억지로 사용할 필요가 없습니다.
재사용 가능성 최적화
대기업에 GraphQL을 배포할 때 개발자들이 다양한 유형의 백엔드를 사용할 수 있어야 하는 경우 종종 문제에 직면합니다. 사업부별로 개발한 서로 다른 스키마 요소가 개발자에게 종종 스키마 제휴의 스키마 병합을 통해 하나의 종합적인 그래프로 제공됩니다. 데이터 표현에 일관성이 없기 때문에 쿼리 동작이 그래프의 부분마다 다른 데이터나 동작을 반환할 경우 문제가 발생합니다. SDL에서 변수 이름이 동일하게 표시되는데 데이터 소스가 다른 것으로 확인된다고 해서 다른 값 또는 형식을 반환해서는 안 됩니다.
또한 요청되는 그래프 부분에 관계없이 릴레이 커서 연결 및 입력 힌트가 모두 일관된 동작을 나타내야 합니다.
이는 특히 변형에서 문제입니다. 개발자가 스키마의 한 부분에 데이터를 특정 방식으로 제출하여 이 데이터가 해당 방식으로 기록될 경우 이 데이터가 스키마의 다른 부분에 제출되었을 때 다른 방식으로 기록되면 알 수 없기 때문입니다. 변형은 재사용 가능성과 API 제품화를 최적화할 때 특히 어려운 과제이므로 GraphQL에서 변형을 개발하고 설계하는 방식을 신중하게 고려해야 합니다.
마지막으로 필드 이름을 살펴보겠습니다. 동일한 이름의 필드 이름에서 스키마의 다른 부분에 있다는 이유로 서로 다른 데이터와 동작을 제공하면 개발자가 어려움을 겪게 됩니다. 예를 들어 스키마의 한 부분에는 이름, 중간 이름, 성이 필요한 이름 필드가 있고 스키마의 다른 부분에는 성과 이름이 필요한 이름 필드가 있다면 이러한 불일치로 인해 개발자가 작업을 포기할 수 있습니다.
GraphQL에서는 쿼리 효율성에 맞춰 최적화하기 쉬우나 재사용 가능성 측면에서 최적화하는 데 목적을 두세요. API가 개발자에게 혼동을 주는 상황을 피하면 큰 도움이 될 것입니다.
REST와 GraphQL 중에서 무엇을 사용하든 API는 관리가 필요한 제품입니다
그래프를 데이터 중심 계층 구조로 취급하는 것에서 재사용 가능성과 개발자 사용 측면에서 최적화하는 것에 이르기까지 대부분의 권장사항이 강조하는 핵심은 성장 전략에 유용한 API는 개발자를 위한 제품이므로 개발자의 API 사용 경험이 API 채택 여부를 결정하는 데 가장 중요한 요소라는 점입니다. 개발자 프로그램에서는 Apigee API 관리의 도움으로 수년 간 REST API를 사용해 이 아이디어를 반영했으며 기업에서 GraphQL에 이를 더 폭넓게 적용함에 따라 앞으로 개발자가 혁신을 이루는 데 이러한 API 프로그램이 더욱 유용하게 사용될 것입니다.
GraphQL과 REST 비교에 대한 자세한 내용은 Google Cloud Next 동영상을 확인하세요. 또한 이 커뮤니티 게시물에서 참조 구현에 관한 유용한 링크와 Apigee에서 GraphQL 쿼리 승인을 사용할 수 있는 도구를 제공하는 GitHub 저장소 링크를 확인할 수 있습니다.