데이터 통신의 3가지 방식. RESTFul API, GraphQL, CQRS에 대한 기초

작성 : 2024-12-20수정 : 2024-12-20

목차 펼치기


머리말

이 글에서는 프론트엔드와 백엔드 간 통신에 사용되는 3가지 패턴에 대해 알아볼게요. 어떤 패턴이 적절한지는 애플리케이션의 기능과 규모, 프로젝트의 상황, 구성원 등에 따라 얼마든지 달라질 수 있으며, 때로는 규칙을 어느 정도 변형하거나 다른 패턴과 결합하여 서로의 장, 단점을 해결할 수 있는 방안을 찾기도 해요.


“모든 것은 트레이드오프가 있다.”
책 ‘Software Architecture: The Hard Parts’ 중에서.

RESTful API

웹 서비스 설계에서 가장 널리 사용되는 표준으로, 리소스를 HTTP 메서드와 URI를 통해 액세스하는 방식이에요.


장점
  1. 단순하고 직관적인 인터페이스

    HTTP 표준을 기반으로 하여 직관적으로 이해하고 활용하기 쉬워요.

  2. 높은 호환성

    다양한 플랫폼 및 언어 간의 상호 운용성을 제공해요.

  3. 확장성

    Stateless 특성 덕분에 확장성이 뛰어나며, 캐싱을 통해 성능도 최적화할 수 있어요.


단점
  1. Over-fetching과 Under-fetching 문제

    클라이언트가 필요하지 않은 데이터도 가져오거나, 필요한 데이터를 위해 여러번 호출해야 하는 문제가 발생할 수 있어요.

  2. 실시간 처리 비적합

    클라이언트가 요청 후 서버가 응답하는 패턴이기 때문에 실시간 통신처럼 서버가 먼저 이벤트를 전송해야 하는 적합하지 않을 수 있어요.

  3. 복잡한 비즈니스 로직 표현의 한계

    CRUD 이외의 복잡한 동작을 HTTP 메서드로 직관적으로 표현하기 어려워요.



이런 경우 고려해보아요
  • 정형화된 리소스 기반으로 단순한 CRUD 작업이 많은 서비스

  • HTTP 캐싱을 활용할 수 있는 경우

  • 표준화된 API 인터페이스가 필요한 경우


GraphQL

효과적으로 클라이언트가 필요한 데이터만 조회하고 응답할 수 있도록 설계된 방식이에요. 페이스북에서 개발한 데이터 쿼리 언어로, 단일 엔드포인트에서 클라이언트가 요청한 데이터 구조에 맞춰 데이터를 응답할 수 있어요.


장점
  1. 클라이언트가 원하는 데이터만 요청할 수 있어요. (Over-fetching 문제를 해결해요).

  2. 복잡한 관계형 데이터를 단일 요청으로 가져올 수 있어요. (Under-fetching 문제를 해결해요).

  3. Subscription을 통해 실시간 데이터 업데이트를 지원해요.


단점
  1. 스키마 설계, 권한 관리, 응답 등에 대해 무척 정교한 설계를 요구하며 러닝커브가 높아요.

  2. 클라이언트가 복잡한 쿼리를 요청하여 서버 성능이 저하될 수 있어요.

  3. 단일 엔드포인트를 사용하기 때문에 HTTP 캐싱이나 CDN 캐싱을 적용할 수 없어요.

    1. 이를 위해 Apollo Client 라이브러리를 사용하여 메모리 상에서 캐싱을 구현할 수는 있어요.

  4. 과도하게 중첩된 데이터를 요청하는 오버로딩이 발생할 수 있어요.


이런 경우 고려해보아요
  • 다양한 클라이언트(웹, 모바일 등)의 요청을 수용해야 하는 서비스

  • 실시간 데이터 피드가 필요한 서비스

  • 복잡한 데이터 구조를 효율적으로 조회해야 하는 경우

  • 네트워크 대역폭이 중요한 경우


CQRS

CQRS(Command Query Responsibility Segregation, 명령 조회 책임 분리)는 읽기 작업(Query)과 쓰기 작업(Command)을 분리하여 각각 독립적으로 처리하는 방식이에요. 데이터를 읽어오는 사이에 데이터가 변경될 수 밖에 없음을 인정하고, 분리하여 처리해요.


읽기와 쓰기 작업에 따라 다른 데이터베이스를 사용하는 것도 가능해요. 예를 들면 MongoDb와 같은 NoSQL 데이터베이스를 사용하여 쓰기 작업을 처리하고, PostgreSql과 같은 SQL 데이터베이스를 사용하여 읽기 작업을 처리할 수 있어요. 이런 구조를 Polyglot이라고 하며, DB 간 동기화를 위해 이벤트 소싱을 활용해요.



장점
  1. 성능 최적화

    읽기와 쓰기를 분리함으로써 각 작업의 요구사항에 최적화된 데이터 모델을 사용할 수 있어요. 이는 시스템 전반의 성능을 크게 향상시킬 수 있어요.

  2. 높은 확장성

    읽기와 쓰기가 독립적이기 때문에, 특정 작업에 대해 개별적으로 확장(Scaling)이 가능해요.

  3. 데이터 일관성 유지 용이

    복잡한 도메인 로직에서도 데이터의 일관성을 체계적으로 관리할 수 있어요.


단점
  1. 복잡도 증가

    데이터 모델과 인프라가 분리되면서 설계 및 구현 과정이 복잡해져요.

  2. 리소스 요구 증가

    유지보수 및 개발에 더 많은 시간과 비용이 소요될 수 있어요.

  3. 데이터 불일치 가능성

    데이터 동기화 지연으로 인해 일시적인 데이터 불일치가 발생할 수 있어요.


이런 경우 고려해보아요
  • 고성능 읽기와 쓰기가 필요하고 그 비율 차이가 큰 서비스

  • 읽기와 쓰기의 요구사항이 매우 다른 경우

  • 이벤트 추적이 필요한 경우

  • 확장성과 복잡성이 중요한 경우



결합 활용

RESTful API + CQRS

CQRS를 통해 내부적으로 읽기/쓰기 로직을 최적화하면서, 외부 인터페이스로 RESTful API를 제공할 수 있어요.

  • CQRS로 도메인 복잡성을 관리

    내부적으로 읽기와 쓰기를 분리하여 복잡한 도메인 로직을 해결해요.

  • RESTful API로 접근성 확보

    외부 개발자 및 서비스와의 통신을 RESTful API 표준으로 제공하여 사용성을 극대화해요.


GraphQL + CQRS 결합 활용
  • GraphQL의 Query 모델에서는 CQRS의 Query 모델을, Mutation 모델에서는 CQRS의 Command Model을 호출하도록 하는 방식이에요.

  • 책임을 분리하고 GraphQL과 CQRS가 제공하는 유연성과 확장성을 극대화할 수 있어요.


참고


Wanna get in touch?

All Icons byiconiFy