Post

REST에서 Socket.io·GraphQL로 확장하기

REST 원칙을 기반으로 실시간 전송과 GraphQL을 단계적으로 조합하는 설계 사고

REST에서 Socket.io·GraphQL로 확장하기

결론 요약

  • 프로토콜 선택은 구현 편의가 아니라 “요구사항의 형태”로 결정된다.
  • REST는 리소스 중심의 상태 전이에 강하고, 실시간은 이벤트 전파 문제다.
  • Socket.io는 REST를 대체하지 않으며, 보완 레이어다.
  • GraphQL은 over/under-fetching을 해결하지만 설계·운영 비용을 전제로 한다.
  • 올바른 확장은 “REST → 실시간 → GraphQL”의 단계적 조합이다.

REST API → 실시간(Socket.io) → GraphQL로 확장하는 설계 사고

요구사항에서 아키텍처로


1️⃣ REST의 핵심 원칙과 흔한 오해

REST의 3대 핵심

  1. 리소스(Resource): URL은 “대상”을 표현한다.
  2. 표현(Representation): JSON/HTML 등은 표현일 뿐이다.
  3. 상태 코드(Status Code): 결과의 의미를 계약으로 전달한다.

흔한 오해: REST = JSON API 실제로 REST는 프로토콜 설계 원칙이지 포맷이 아니다.

올바른 REST 예

1
2
3
4
GET /posts/123        → 게시물 조회
POST /posts           → 게시물 생성
PATCH /posts/123      → 게시물 수정
DELETE /posts/123     → 게시물 삭제

URL에 /create, /delete 같은 행동 동사가 보이면 REST 사고가 깨진 신호다.


2️⃣ CORS: 왜 생기고, 어디서 해결하는가

CORS가 생기는 이유

  • 브라우저는 출처(origin) 간 요청을 제한한다.
  • 서버가 아니라 브라우저 보안 정책이다.

어디서 해결해야 하는가

  • 서버에서 헤더로 허용 범위를 명시한다.
  • 클라이언트에서 우회하려는 시도는 근본 해결이 아니다.
1
2
3
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers

설계 포인트

  • 인증 토큰(JWT)을 쓰면 CORS 설정은 더 엄격해져야 한다.
  • 와일드카드(*)는 개발 단계에서만 허용.

3️⃣ REST에서 인증(JWT) 흐름과 권한 체크 위치

JWT 기반 인증 흐름 (REST)

1
2
3
4
5
POST /login
 → JWT 발급
 → Client 저장
 → Authorization: Bearer <token>
 → 보호된 API 접근

권한 체크 위치

  • 라우트 진입 시 미들웨어
  • 비즈니스 로직 내부가 아니다.
1
authenticate  authorize  controller

중요 분리

  • Authentication: 토큰 유효성
  • Authorization: 역할/권한 확인

이 분리가 안 되면 “로그인만 하면 관리자 행동 가능”한 사고가 난다.


4️⃣ 실시간이 필요한 조건과 Socket.io의 위치

실시간이 필요한 조건

  • 상태 변경을 즉시 다수에게 전파
  • polling 비용이 과도함
  • 사용자 체감 지연이 UX를 깨뜨림

예:

  • 채팅
  • 알림
  • 협업 편집
  • 실시간 상태판

Socket.io의 정확한 위치

  • REST를 대체하지 않는다
  • REST로 상태 변경 → 이벤트를 실시간으로 전파
1
2
REST: 데이터의 진실(source of truth)
Socket.io: 변화의 전달(channel)

이 경계를 넘으면 상태 불일치가 발생한다.


5️⃣ GraphQL: 장점과 비용을 동시에 본다

GraphQL의 장점

  • over-fetching 제거: 필요한 필드만 요청
  • under-fetching 제거: 한 번의 요청으로 조합
  • 프론트엔드 주도 쿼리 설계

하지만 반드시 치르는 비용

항목비용
스키마 설계초기 설계 난이도 높음
리졸버서버 복잡도 증가
N+1 문제잘못 설계하면 성능 급락
캐싱REST보다 난이도 높음

GraphQL은 “API를 예쁘게 만드는 도구”가 아니라 요청 패턴이 복잡할 때만 가치가 생기는 도구다.


6️⃣ REST vs GraphQL 비교표

항목RESTGraphQL
요청 단위엔드포인트쿼리
데이터 제어서버클라이언트
캐싱쉬움어려움
스키마암묵적명시적
성능예측 가능설계 의존
운영단순복잡

7️⃣ 설계 시 흔히 깨지는 지점과 해결 패턴

❌ 나쁜 패턴

  • 모든 API를 GraphQL로 시작
  • 실시간 요구 없이 Socket.io 도입
  • REST에서 권한 체크 누락

✅ 개선 패턴

  • REST로 명확한 데이터 경계 먼저 구축
  • 실시간은 “필요한 이벤트만” 추가
  • GraphQL은 프론트 요구가 복잡해질 때 도입

8️⃣ 결론: 5가지 서비스 시나리오로 선택하기

  1. 블로그 / CMS
    • REST + SSR
    • 필요 시 관리자 실시간 알림
  2. 커머스
    • REST (주력)
    • Socket.io (재고/주문 상태)
    • GraphQL은 선택
  3. 채팅 / 협업
    • REST (기본 데이터)
    • Socket.io (핵심 기능)
  4. 모바일 API
    • REST + JWT
    • GraphQL은 복잡한 피드에만 제한 사용
  5. 대규모 프론트 팀
    • REST → GraphQL 점진 도입
    • 스키마/권한/캐싱 전략 필수

설계 선택 체크리스트 (질문 12개)

  • URL이 리소스를 표현하고 있는가?
  • 상태 코드를 계약으로 사용하고 있는가?
  • CORS를 서버에서 제어하고 있는가?
  • 인증과 권한을 분리했는가?
  • REST가 source of truth인가?
  • 실시간이 정말 필요한가?
  • 이벤트 전파와 상태 변경을 분리했는가?
  • over/under-fetching 문제가 실제로 존재하는가?
  • GraphQL N+1을 방지할 설계가 있는가?
  • 캐싱 전략을 설명할 수 있는가?
  • 운영 복잡도를 감당할 수 있는가?
  • 6개월 뒤에도 이 선택을 유지할 수 있는가?

This post is licensed under CC BY 4.0 by the author.