이벤트 기반 시스템에서 REST API 레이어 구축 전략
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
웹 개발
대상자
이벤트 소싱(Event Sourcing) 아키텍처와 REST API를 결합하는 백엔드 개발자, 시스템 설계자
핵심 요약
- 이벤트 기반 상태 추적:
OrderProjection
클래스를 통해 이벤트를 현재 상태로 변환 (예:status: :placed
) - REST API와 이벤트 소싱 통합:
PATCH /orders/{id}
요청을ApplyDiscount
도메인 명령으로 변환 - 버전 관리 최적화: ETag 기반의
If-Match
헤더로 스트림 버전 검증 ("stream_version_42"
) - 프로젝션 유지 전략:
OrderProjectionV2
에서DiscountApplied
이벤트를 기존 로직과 병합
섹션별 세부 요약
1. 이벤트 기반 상태 관리의 도전
- 이벤트 기록(예:
OrderPlaced
)은 현재 상태를 직접 제공하지 않음 OrderProjection
클래스로 이벤트를 축약된 JSON 상태(status
,items
,created_at
)로 변환apply(event, state)
메서드에서 이벤트 타입에 따라 상태 업데이트 (예:OrderShipped
→status: :shipped
)
2. REST API와 이벤트 명령 처리
/orders/:id/ship
엔드포인트에서ShipOrder
명령 실행 후 이벤트(OrderShipped
) 발행Idempotency-Key
헤더로 중복 요청 방지 (예:IdempotencyStore.unique?
)ETag
헤더를 통해 스트림 버전 검증 (예:If-Match: "stream_version_42"
)
3. 도메인 명령 기반 PATCH 요청 처리
PATCH /orders/{id}
요청을ApplyDiscount
명령으로 변환 (예:op: "add_discount"
)OrderProjectionV2
에서DiscountApplied
이벤트를discounts
필드에 병합
4. 프로젝션 캐싱 및 쿼리 최적화
Rails.cache
로 프로젝션 결과 캐싱 (예:expires_in: 5.minutes
)CREATE MATERIALIZED VIEW api_orders
로 공통 쿼리 사전 생성GET /orders/{id}?fields=id,status
로 특정 필드만 반환 (프로젝션 우회)
5. 도구 및 아키텍처 선택
- RailsEventStore HTTP API: 이벤트 스트림 REST 노출
- GraphQL: 프로젝션의 유연한 쿼리 지원
- OpenAPI: 명령 기반 엔드포인트 문서화
- 제한 사항: 공공 CRUD API, 고속 거래 시스템은 이벤트 기반 아키텍처에 부적합
결론
- 이벤트 기반 시스템에서 REST API 레이어 구축 시
OrderProjection
프로젝션과ETag
버전 관리 사용 권장 PATCH
요청을 도메인 명령으로 변환하여 상태 일관성 유지Materialized View
와Rails.cache
를 활용한 쿼리 성능 향상- 공공 CRUD API는 이벤트 기반 아키텍처에 부적합한 경우를 명확히 구분하여 설계