REST와 GraphQL 비교

2025. 11. 4. 23:56·WEB

들어가며

REST vs GraphQL

이전 직장에서 REST API로 구축된 프로젝트를 GraphQL로 전환하는 과정을 경험했습니다. 이 경험을 통해 오랫동안 웹 API의 표준처럼 여겨져 온 REST의 자원(Resource) 중심 접근 방식과, 최신 애플리케이션의 복잡한 데이터 요구에 맞춰 등장한 GraphQL의 클라이언트 중심 접근 방식이 어떻게 다른지 체감할 수 있었습니다. 좀 더 명확한 차이점을 이해하기 위해 각 기술이 어떻게 탄생했고, 어떤 핵심 원칙을 가지고 있는지, 그리고 실제 어떤 상황에 사용하면 좋은지, 나아가 캐싱이나 보안 방식의 차이점까지 조사했습니다.


REST란? — 웹을 위해 만들어진 아키텍처 스타일

REST의 탄생

등장 배경과 동기

REST는 2000년 로이 필딩의 박사 논문에서 처음으로 소개되었습니다. 그의 논문에서 정의한 REST는 특정 프로토콜이나 표준이 아닌, 분산 하이퍼미디어 시스템을 위한 아키텍처 스타일입니다. 이 스타일은 월드 와이드 웹의 기존 아키텍처(HTTP 1.0/1.1, URI)를 분석하여, 웹을 확장 가능하고 견고하게 만든 핵심 원칙을 분석하는 과정에서 REST가 탄생했습니다. 로이 필딩은 웹이 스스로의 복잡성 때문에 무너지지 않도록, 지켜야 할 아키텍처 원칙들의 집합으로 REST를 제안했습니다.

6가지 핵심 원칙

  • 클라이언트-서버 (Client-Server): 이 원칙은 역할과 책임의 분리를 명확히 합니다. 클라이언트는 사용자 인터페이스(UI)와 사용자 경험(UX)에 집중하고, 서버는 데이터 저장, 비즈니스 로직, 보안을 책임집니다. 이렇게 역할을 나누면 클라이언트와 서버가 서로에게 영향을 주지 않고 독립적으로 개발하고 발전할 수 있어, 전체 시스템의 유연성과 확장성을 높여줍니다.
  • 무상태 (Stateless): 서버는 클라이언트의 상태(세션 정보 등)를 저장하지 않습니다. 클라이언트가 서버로 보내는 각 요청에는 서버가 그 요청을 이해하고 처리하는 데 필요한 모든 정보가 담겨 있어야 합니다. 이 원칙 덕분에 서버 설계가 단순해지고, 각 요청을 독립적으로 처리할 수 있어 가시성, 신뢰성, 확장성을 크게 높여줍니다. 서버가 이전 요청을 기억할 필요가 없으니 부하 분산이 쉬워지고, 장애가 생겨도 복구하기가 더 수월해집니다.
  • 캐시 가능 (Cacheable): 서버가 보내는 응답에는 이 응답을 캐시(임시 저장)해도 되는지 여부를 명시해야 합니다. 클라이언트나 중간 서버는 캐시 가능한 응답을 재사용해서, 똑같은 요청이 또 들어왔을 때 서버까지 가지 않고 캐시에서 바로 응답을 보내줄 수 있습니다. 이는 서버 부하를 줄이고 응답 속도를 높여줍니다. 네트워크 효율성을 높여 사용자가 느끼는 성능을 크게 개선하는 핵심 요소입니다.
  • 계층화 시스템 (Layered System): 클라이언트는 자신이 통신하는 서버가 최종 목적지인지, 아니면 중간에 로드 밸런서나 캐시 같은 다른 계층을 거치는지 알 필요가 없습니다. 각 계층은 보안, 부하 분산 등 특정 기능을 담당하며 다른 계층과 독립적으로 작동합니다. 이 구조는 시스템의 복잡도를 관리하고 기존 시스템을 쉽게 통합하는 데 도움을 줍니다.
  • 인터페이스 일관성 (Uniform Interface): REST를 다른 아키텍처와 가장 뚜렷하게 구분 짓는 핵심 원칙입니다. 시스템 전체의 아키텍처를 단순화하고, 클라이언트와 서버가 독립적으로 발전할 수 있도록 해줍니다. 이 원칙은 다시 네 가지 세부 원칙으로 나뉘며, 다음 섹션에서 자세히 다루겠습니다.
  • 코드 온디맨드 (Code-On-Demand, 선택 사항): 서버가 클라이언트로 실행 가능한 코드(예: JavaScript)를 보내 클라이언트의 기능을 일시적으로 확장할 수 있게 해주는 원칙입니다. 필수는 아니지만, 클라이언트가 미리 모든 기능을 구현할 필요가 없게 만들어 시스템을 더 단순하게 만들 수 있습니다.

이상과 현실의 차이: '진정한 REST', HATEOAS, 리처드슨 성숙도 모델

인터페이스 일관성의 네 가지 세부 원칙

  1. 자원의 식별 (Identification of Resources): 시스템의 모든 자원은 URI(Uniform Resource Identifier)라는 고유한 주소를 통해 식별됩니다. 예를 들어, 특정 사용자는 /users/123과 같은 주소로 표현됩니다. URI를 설계할 때는 보통 동사 대신 명사를 사용하고, 여러 자원의 모음을 나타낼 때는 복수형을 씁니다.
  2. 표현을 통한 자원의 조작 (Manipulation of Resources Through Representations): 클라이언트는 자원의 상태를 직접 바꾸는 게 아니라, 자원의 표현(예: JSON 데이터)을 통해 상호작용합니다. 클라이언트는 이 표현과 함께 표준 HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용해 서버에 무엇을 하고 싶은지 전달합니다.
  3. 자기 서술적 메시지 (Self-Descriptive Messages): 각 메시지는 메시지를 받는 쪽에서 그 메시지를 어떻게 처리해야 하는지 충분한 정보를 스스로 담고 있어야 합니다. 예를 들어, Content-Type 헤더에 application/json이라고 명시해서 '이 메시지 본문은 JSON 형식이니 JSON 파서로 처리하세요'라고 알려주는 식입니다.
  4. 애플리케이션 상태의 엔진으로서 하이퍼미디어 (Hypermedia as the Engine of Application State, HATEOAS): 서버의 응답에는 현재 자원과 관련하여 다음에 할 수 있는 행동이나 이동할 수 있는 상태에 대한 링크(하이퍼미디어)가 포함되어야 합니다. 예를 들어, 특정 주문(order) 정보를 조회했을 때, 응답 데이터 안에 그 주문을 '취소'하거나 '결제'할 수 있는 URL 링크가 함께 제공되는 것입니다. REST 아키텍처에서 가장 중요하지만, 잘 지켜지지 않는 원칙입니다.

현실과의 거리: HATEOAS는 어디에?

HATEOAS를 구현한 API는 응답되는 링크를 통해서 비지니스 규칙(예: 구매가 가능할 때에는 구매에 대한 링크를 제공하지만 불가능할 경우 링크를 제공하지 않음)을 서버에 이관하고, 클라이언트에서는 제공받은 링크를 기반으로 개발함으로써 URI변경에 대한 서버와 클라이언트의 관계의 유연성을 제공하지만, 이를 위해 응답되는 링크의 의미와 관계에 대한 인지적 부하와 학습 곡선과 백엔드 개발 비용 증가 등의 단점이 있습니다.

이처럼 서버(동적 링크 생성)와 클라이언트(하드코딩된 URL 대신 링크 파싱) 양쪽에 구현 복잡성을 더하기 때문에 오늘날 우리가 "REST API"라고 부르는 대부분의 API는 인터페이스 일관성의 첫 세 가지 원칙은 잘 따르지만, HATEOAS는 거의 지키지 않습니다. 로이 필딩은 이런 API는 진정한 REST가 아니라 그냥 HTTP 기반 API일 뿐이라고 말하였습니다.(출처)

그러나 로이 필딩의 생각과 달리, 일부 원칙만 지키면서도 RESTful API라 부르는 사례가 많아지자 리처드슨은 레벨을 나누어 어떤 정도의 RESTful 수준인지 표시하는 모델을 제안했습니다.

리처드슨 성숙도 모델

  • Level 0: HTTP를 그냥 원격 함수 호출(RPC)을 위한 전송 수단으로만 사용합니다. 모든 요청이 하나의 엔드포인트로 가고, HTTP 메서드는 무시됩니다.
  • Level 1: '자원'이라는 개념을 도입합니다. 각 자원은 고유한 URI를 갖지만, 여전히 모든 작업에 POST 메서드를 쓰는 등 HTTP를 제대로 활용하지는 않습니다.
  • Level 2: HTTP 메서드를 의미에 맞게 사용합니다. GET은 조회, POST는 생성, PUT은 수정, DELETE는 삭제에 사용합니다. 오늘날 우리가 "REST API"라고 부르는 대부분의 API가 이 수준에 해당합니다.
  • Level 3: HATEOAS를 도입하여 진정한 REST의 모든 원칙을 만족시킵니다. 클라이언트는 서버가 제공하는 링크를 통해 다음 행동을 결정합니다.

GraphQL의 등장 — 최신 애플리케이션을 위한 쿼리 언어

등장 배경 - 페이스북의 모바일 우선 전략과 그에 따른 과제

문제의 시작

2010년대 초, 페이스북은 모바일 앱을 웹 기반(HTML5)에서 네이티브 앱으로 전환하면서 심각한 성능 문제에 부딪혔습니다. 페이스북의 뉴스 피드는 게시물, 작성자 정보, 댓글, 댓글 작성자 정보, 각 항목의 '좋아요' 수 등 여러 데이터가 복잡하게 얽혀 있어 한 번에 가져와야 했습니다.

오버페칭과 언더페칭 문제

기존의 REST API 방식으로는 이런 데이터를 효율적으로 가져오기 어려웠고, 두 가지 주요 문제가 발생했습니다.

  • 언더페칭 (Under-fetching): 클라이언트가 화면을 구성하는 데 필요한 모든 데이터를 모으기 위해 서버에 여러 번 요청을 보내야 하는 문제입니다. 예를 들어, GET /posts/123으로 게시물 정보를 가져오고, 그 응답에 담긴 작성자 ID로 다시 GET /users/456을 호출하고, 또 GET /posts/123/comments를 호출하는 식이죠. 이렇게 여러 번의 요청이 오가는 것은 특히 네트워크 지연 시간이 긴 모바일 환경에서 성능에 치명적인 영향을 줍니다.
  • 오버페칭 (Over-fetching): 여러 번 요청하는 것을 피하기 위해, 서버에서 /feed처럼 필요한 모든 정보를 한 번에 내려주는 전용 엔드포인트를 만들 수도 있습니다. 하지만 이 경우, 클라이언트는 당장 화면에 필요하지 않은 데이터까지 모두 포함된 거대한 데이터를 받아야 합니다. 이는 네트워크 대역폭을 낭비하고 클라이언트의 처리 부담을 늘립니다.

GraphQL은 2012년 페이스북 내부에서 바로 이 문제를 해결하기 위해 개발되었고, 2015년에 오픈소스로 공개되었습니다. GraphQL의 핵심 아이디어는 간단합니다. 데이터의 형태를 서버가 아닌 클라이언트가 결정하도록 권한을 넘겨주는 것입니다. 클라이언트가 필요한 데이터의 구조를 정확히 명시해서 요청하면, 서버는 그 구조에 딱 맞춰서 응답을 제공합니다.

핵심 구성 요소

GraphQL의 아키텍처는 REST 모델과는 정반대의 접근 방식을 취합니다. REST가 자원별로 여러 개의 단순한 엔드포인트를 제공하는 반면, GraphQL은 복잡한 쿼리를 이해할 수 있는 하나의 똑똑한 엔드포인트를 제공합니다. 이 구조적 차이가 데이터 요청 효율성부터 캐싱의 복잡성까지, 두 방식의 거의 모든 주요 차이점을 만들어냅니다. REST에서는 API 호출의 의미가 URI와 HTTP 메서드에 담겨 있지만(엔드포인트 자체가 작업을 정의), GraphQL에서는 POST 요청의 본문에 담긴 쿼리 자체에 그 의미가 담겨 있습니다.

  • 스키마 정의 언어 (Schema Definition Language, SDL): 모든 GraphQL API의 심장은 '스키마'입니다. 스키마는 이 API가 어떤 데이터를 제공할 수 있고, 어떤 작업을 할 수 있는지 모든 것을 정의하는, 강력한 타입 시스템 기반의 계약서와 같습니다. 이 스키마는 클라이언트와 서버 사이의 "단일 진실 공급원(single source of truth)" 역할을 하며, 특정 프로그래밍 언어에 얽매이지 않고 객체 타입, 필드, 그리고 그 관계를 명확하게 정의합니다.
  • 쿼리, 뮤테이션, 구독: GraphQL에는 세 가지 주요 작업 유형이 있습니다.
    • 쿼리 (Query): 데이터를 읽을 때 사용합니다. 클라이언트는 자신이 받고 싶은 JSON 응답의 모양과 똑같은 형태로 쿼리를 작성해서 보내기 때문에, 오버페칭과 언더페칭 문제를 근본적으로 해결할 수 있습니다.
    • 뮤테이션 (Mutation): 데이터를 생성, 수정, 삭제할 때 사용합니다.
    • 구독 (Subscription): 웹소켓 등을 통해 실시간으로 데이터 업데이트를 받아보기 위한 지속적인 연결을 만들 때 사용합니다.
  • 리졸버 (Resolver): 서버에서는 스키마의 각 필드마다 '리졸버'라는 함수가 연결됩니다. 이 함수는 해당 필드에 대한 데이터를 실제로 어떻게 가져올지(데이터베이스에서 가져오거나, 다른 API를 호출하는 등)에 대한 로직을 담고 있습니다.

강력한 타입 시스템을 갖춘 스키마는 기술적 세부사항을 넘어, API 명세서 자체로 기능합니다.


REST와 GraphQL 비교

REST와 GraphQL의 기능별 비교

기능 REST API GraphQL
데이터 요청 서버가 데이터 구조를 정의. 엔드포인트마다 고정된 데이터를 반환. 오버/언더페칭이 발생하기 쉬움. 클라이언트가 데이터 구조를 정의. 쿼리에 따라 유연하게 데이터를 반환. 오버/언더페칭 문제 해결.
엔드포인트 여러 개의 엔드포인트. 각 자원마다 하나씩 (예: /users, /posts). 일반적으로 단 하나의 엔드포인트 (예: /graphql).
프로토콜 HTTP 메서드(GET, POST, PUT, DELETE)로 작업을 표현. 주로 모든 작업(쿼리, 뮤테이션)에 POST 메서드를 사용.
타입 시스템 약한 타입. JSON Schema 등으로 타입을 정의할 수는 있지만, 강제되지는 않음. 스키마 정의 언어를 통한 강력한 타입 시스템. 클라이언트와 서버 간의 계약이 강제됨.
캐싱 표준 HTTP 캐싱(헤더 ETag, Cache-Control 등)을 통해 쉽게 구현 가능. 단일 엔드포인트를 사용하므로 HTTP 캐싱이 복잡함. 클라이언트 라이브러리나 애플리케이션 레벨에서 캐싱 처리.
버전 관리 주로 URI에 버전을 명시 (예: /v1/users). 스키마를 점진적으로 발전시키는 방식을 선호. 필드를 제거하는 대신 '사용 중단(deprecated)'으로 표시.
에러 처리 HTTP 상태 코드로 요청 전체의 성공/실패를 표시 (예: 404, 500). 주로 200 OK 상태 코드와 함께, 응답 본문 내 errors 배열에 에러 정보를 담아 반환.
API 명세 탐색 내장된 표준이 없어 OpenAPI/Swagger 같은 외부 문서에 의존. 내장된 '인트로스펙션' 기능으로 클라이언트가 스키마 자체에 쿼리하여 API 구조를 탐색할 수 있음.

개발자 경험과 API의 발전

  • API 탐색과 문서화: REST는 API의 구조와 사용법을 이해하기 위해 Swagger나 OpenAPI 같은 외부 문서 도구가 필요합니다. 반면, GraphQL은 '인트로스펙션'이라는 기능이 내장되어 있어, 클라이언트가 API 스키마 자체에 쿼리를 보내 사용 가능한 모든 타입과 필드를 동적으로 알아낼 수 있습니다. GraphiQL 같은 도구는 이를 시각적으로 보여주어 API를 탐색하고 테스트하는 강력한 개발 환경을 제공합니다.
  • 버전 관리: REST API는 기존 API와 호환되지 않는 변경이 생길 때, 보통 URI에 버전을 붙이는 방식(예: /v2/users)을 사용합니다. 이는 여러 버전의 API를 동시에 유지보수해야 하는 부담을 줍니다. GraphQL은 버전 관리 대신 진화하는 방식을 권장합니다. 새로운 필드는 기존 클라이언트에 영향을 주지 않고 스키마에 추가할 수 있고, 더 이상 사용하지 않는 필드는 바로 삭제하는 대신 @deprecated 지시어를 붙여 사용 중단으로 표시할 수 있습니다. 이를 통해 API가 점진적으로 발전해 나갈 수 있습니다.
  • 클라이언트 측 복잡성: GraphQL이 데이터 요청 로직을 단순화해주는 반면, 상태 관리나 캐싱 같은 부분에서는 클라이언트 측의 복잡성을 높일 수 있습니다. 이 때문에 보통 Apollo Client나 Relay처럼 정교한 기능을 제공하는 라이브러리를 함께 사용하게 됩니다.

캐싱 문제: 두 아키텍처의 근본적인 차이점

캐싱 전략의 차이는 두 아키텍처의 근본적인 철학 차이에서 비롯됩니다. REST의 여러 개의 단순한 엔드포인트와 GraphQL의 하나의 똑똑한 엔드포인트라는 핵심 설계가 캐싱 방식의 차이를 만드는 직접적인 원인입니다.

  • REST와 HTTP 캐싱: REST 아키텍처는 오랜 시간 발전해온 웹 인프라와 잘 어우러집니다. GET /users/123과 같은 요청은 여러 번 호출해도 결과가 같고(멱등성), 그 응답은 브라우저, CDN, 리버스 프록시 등 모든 표준 HTTP 캐시가 저장하고 재사용할 수 있습니다. Cache-Control, ETag, Last-Modified 같은 표준 HTTP 헤더를 통해 캐시 정책을 세밀하게 제어할 수 있습니다. 이는 추가 개발 비용 없이 엄청난 성능과 확장성 이점을 얻을 수 있는, REST가 가진 강력하면서도 종종 간과되는 장점입니다.
  • GraphQL의 캐싱 과제: 대부분의 GraphQL 쿼리는 단일 엔드포인트(예: /graphql)에 POST 메서드로 전송되기 때문에, 표준 HTTP 캐시 입장에서는 요청의 내용을 알 수 없습니다. 캐시는 요청 URL을 기준으로 작동하는데, GraphQL 요청은 URL이 항상 같아서 사용자를 조회하는 쿼리와 제품을 조회하는 쿼리를 구분할 수 없기 때문입니다. 즉, GraphQL의 설계는 가장 일반적이고 강력한 웹 캐싱 방식을 포기하는 대신, 다른 장점을 선택한 것입니다. 이는 설계 실수가 아니라, 클라이언트가 원하는 대로 데이터를 요청하게 한다는 핵심 목표를 달성하기 위한 필연적인 트레이드오프입니다.
  • GraphQL의 해결책: GraphQL 환경에서 캐싱의 책임은 전송 계층(HTTP)에서 애플리케이션 계층으로 넘어갑니다. 캐싱은 주로 Apollo Client나 Relay 같은 클라이언트 라이브러리가 담당합니다. 이 라이브러리들은 데이터 객체를 정규화하여 메모리에 캐시를 만들어두고, 동일한 데이터에 대한 중복 요청을 막고 UI를 즉각적으로 업데이트해 줍니다. 이는 매우 강력하지만, 단순한 HTTP 캐싱에 비해 구현하고 관리하기가 더 복잡합니다.

보안 방식의 차이

REST API의 보안 방식

  • 인증 및 인가: REST API 보안은 이미 잘 알려진 패턴을 따릅니다. API 키, HTTP 기본 인증(HTTPS와 함께 사용), JWT(JSON Web Tokens), OAuth 2.0 같은 표준적인 방법들이 널리 사용됩니다. 인가(권한 부여)는 보통 엔드포인트 단위로 처리됩니다. 예를 들어, 특정 사용자가 DELETE /users/{id} 엔드포인트에 접근할 권한이 있는지 확인하는 방식입니다.
  • 전송 계층 보안: 데이터를 주고받는 과정에서 정보를 보호하기 위해 HTTPS(TLS)를 사용하는 것은 선택이 아닌 필수입니다.
  • 요청 횟수 제한 (Rate Limiting & Throttling): 서비스 거부(DoS) 공격이나 시스템 남용을 막기 위한 핵심적인 방어 수단입니다. 보통 API 게이트웨이나 로드 밸런서에서 구현하며, 엔드포인트별, 사용자별, 또는 IP 주소별로 정해진 시간 동안의 요청 횟수를 제한합니다.
  • 입력값 검증: SQL 인젝션 같은 공격을 막기 위해, 클라이언트로부터 들어오는 모든 데이터(쿼리 파라미터, 요청 본문 등)를 철저히 검증해야 합니다.

GraphQL API의 보안 방식

GraphQL의 "하나의 똑똑한 엔드포인트" 구조는 그 자체로 독특한 보안 과제를 만듭니다. REST에서는 /users와 /admin/reports처럼 각기 다른 엔드포인트에 대해 요청 횟수 제한이나 권한 규칙을 간단하게 적용할 수 있습니다. 하지만 GraphQL에서는 모든 요청이 /graphql로 들어오기 때문에, 이런 보안 제어는 요청 본문을 직접 파싱해서 동적으로 결정을 내리는 애플리케이션 로직 안으로 더 깊숙이 들어와야 합니다.

  • 인증 및 인가: 인증은 REST와 비슷하게 처리할 수 있습니다(예: HTTP 헤더에 JWT 전달). 하지만 인가는 훨씬 더 복잡합니다. 단일 엔드포인트 구조 때문에 '라우트' 수준에서 권한을 검사할 수 없습니다. 이는 GraphQL에서 쿼리를 확인하기 전까지는 무엇을 하려는 것인지 알 수 없기 때문입니다. 그에 따라 인가는 스키마의 각 필드나 타입에 대한 리졸버 안에서 구현되어야 합니다.
  • 복잡한 쿼리를 통한 서비스 거부 (DoS) 공격: 이는 GraphQL의 고유한 취약점입니다. 공격자는 의도적으로 아주 깊게 중첩되거나 순환하는 쿼리를 보내 서버의 자원(CPU, 메모리, 데이터베이스 연결)을 고갈시킬 수 있습니다.
    • 방어 전략: 이런 공격을 막기 위해서는 쿼리 깊이 제한(쿼리가 중첩될 수 있는 최대 깊이를 제한), 쿼리 복잡도 분석(각 필드에 '비용' 점수를 매기고, 총비용이 정해진 값을 넘는 쿼리는 거부), 타임아웃 설정 같은 방어 장치를 구현해야 합니다.
  • 인트로스펙션 쿼리: GraphQL은 기본적으로 클라이언트가 인트로스펙션 쿼리를 통해 전체 스키마 정보를 조회할 수 있게 허용합니다. 외부에 공개되지 않는 API의 프로덕션 환경에서 이 기능이 켜져 있으면, 공격자에게 API의 내부 구조, 사용 가능한 모든 쿼리와 뮤테이션, 데이터 타입 등 민감한 정보를 그대로 노출할 수 있습니다.
    • 방어 전략: 외부에 공개되지 않는 API의 경우, 프로덕션 환경에서는 인트로스펙션 기능을 비활성화하는 것이 강력히 권장됩니다.

그래서, 언제 무엇을 써야 할까요?

REST를 선택하면 좋은 경우: 단순성, 표준, 캐싱이 중요할 때

  • 공개 API (Public APIs): 안정적이고, 문서화가 잘 되어 있으며, 사용하기 쉬운 공개 API를 만들 때는 REST의 표준화된 구조와 예측 가능성이 큰 장점입니다. 개발자 생태계가 이미 REST에 익숙하기 때문에 새로운 사용자들이 쉽게 적응할 수 있습니다.
  • 자원 중심 시스템: 제공하는 서비스가 명확한 자원들로 나뉘고, 클라이언트가 주로 자원의 전체 정보를 필요로 하는 경우(예: 제품 관리를 위한 간단한 CRUD 서비스) REST는 매우 효율적이고 직관적입니다.
  • 캐싱이 매우 중요한 서비스: 애플리케이션 성능이 CDN이나 중간 캐시에 크게 의존하고, 응답 데이터가 자주 캐시될 수 있는 경우, REST가 HTTP 캐싱과 완벽하게 호환된다는 점은 결정적인 이점입니다.
  • 단순한 클라이언트 또는 제한된 개발 환경: 개발팀이 복잡한 클라이언트 라이브러리나 상태 관리의 부담을 피하고 싶을 때, REST의 단순함은 매력적인 선택이 될 수 있습니다.

GraphQL을 선택하면 좋은 경우: 유연성, 효율성, 복잡한 시스템

  • 복잡하고 중첩된 데이터: 데이터 모델이 서로 복잡하게 얽혀 있어 클라이언트가 이 관계를 자주 탐색해야 하는 경우(예: 소셜 네트워크, 콘텐츠 관리 시스템) GraphQL이 좋은 선택이 될 수 있습니다.
  • 마이크로서비스 집계 (API 게이트웨이): GraphQL은 여러 마이크로서비스(이들 자체는 REST API일 수 있음) 앞에 위치하는 게이트웨이 역할로 매우 효과적입니다. 이 게이트웨이는 클라이언트에게는 하나의 통일된 GraphQL 스키마를 제공하기 때문에 클라이언트에서 여러 마이크로서비스의 URL에 대한 관리포인트가 줄어드는 등의 이점이 있습니다.

마치며

이전 직장에서 GraphQL을 사용하며 프론트엔드 개발자가 필요한 데이터만 정확히 조회하는 것, 그리고 특히 컴포넌트가 필요로 하는 데이터를 프래그먼트(Fragment)로 함께 선언하여 컴포넌트와 데이터 간의 응집도를 높이는 방식은 매력적이었습니다.

하지만 겪어본 입장에서, 표준적으로 사용되는 RESTful API에 비해 GraphQL의 초기 러닝커브는 확실히 높다고 생각합니다. 특히 Relay 라이브러리를 사용했는데, 방대한 기능에 비해 문서가 다소 불친절하게 느껴졌습니다. 또한 프로젝트가 커지고 스키마에 정의된 객체 타입(Object Type)이 워낙 많아지다 보니, 쿼리 작성 시 어떤 타입이 어떤 필드를 가지고 있고 서로 어떻게 연결되는지 그 관계를 파악하는 것이 헷갈릴 때도 있었습니다.

GraphQL은 REST API보다 무조건 좋은 기술은 아닙니다. GraphQL과 Relay가 제공하는 '개발 유연성'과 '네트워크 효율성'이라는 강력한 이점은, '초기 높은 학습 비용', '클라이언트/서버의 복잡성 증가'라는 명확한 비용과 교환하는 것입니다.

이처럼 기술을 선택함에 있어서 최신 기술이라고 무조건 사용하는 것보다 현재 우리팀의 목표와 해결하고자 하는 문제를 고민하여 선택할 수 있는 눈을 기를 수 있도록 노력하고자 합니다.

저작자표시 비영리 변경금지 (새창열림)

'WEB' 카테고리의 다른 글

쿠키, 세션(cookie, session)과 토큰 (token, JWT)의 차이점  (0) 2022.04.19
웹에서 사용하는 이미지  (0) 2019.05.23
웹표준과 웹 접근성  (0) 2019.05.23
REST API란?  (0) 2019.05.21
REST란?  (0) 2019.05.16
'WEB' 카테고리의 다른 글
  • 쿠키, 세션(cookie, session)과 토큰 (token, JWT)의 차이점
  • 웹에서 사용하는 이미지
  • 웹표준과 웹 접근성
  • REST API란?
vitnal
vitnal
4년차 프론트엔드 개발자입니다. react를 사용하여 웹 서비스를 개발한 경험이 있습니다. github: https://github.com/jch1223
  • vitnal
    vitnal 아카이브
    vitnal
  • 전체
    오늘
    어제
    • 분류 전체보기 (146)
      • AI (1)
      • WEB (76)
        • React (21)
        • Nextjs (17)
        • JavaScript (16)
        • React Native (5)
        • HTML & CSS (7)
      • CS (3)
      • Git (15)
      • Dev Tools (23)
      • Deploy (12)
      • Tech Memo (8)
      • Retrospect (7)
  • 반응형
  • hELLO· Designed By정상우.v4.10.5
vitnal
REST와 GraphQL 비교
상단으로

티스토리툴바