REST API | WebSocket (STOMP) |
---|---|
HTTP 기반 (Request → Response) | Persistent 연결 (연결 유지) |
URL + Method 기반 라우팅 (@GetMapping, @PostMapping) | destination 기반 라우팅 (@MessageMapping) |
BaseResponse 등으로 표준화 쉽게 가능 | 실시간 메시지 → 이벤트 기반 → BaseResponse가 잘 안 맞음 (실시간 응답은 주로 payload 자체로 보냄) |
요청-응답 명확 | pub/sub 구조, 실시간 Push |
팀 컨벤션이 확실하게 있는데, 웹소켓으로 기능을 구현하고자 하니 지킬 수 없게되었다.
그런데 그게 정상이라고 한다.
WebSocket용 코드에서는 팀 REST 컨벤션 (BaseResponse 래핑 등)을 "그대로 적용하려고 억지로 할 필요 없음"
→ WebSocket은 @MessageMapping
+ Plain Object (DTO)
로 처리하는 게 자연스러움
기능 | 구현 방법 |
---|---|
방 생성 (초기화 등) | REST API 로 처리 → 팀 컨벤션 따름 → BaseResponse 사용 |
실시간 채팅 (메시지 송수신) | WebSocket → @MessageMapping 사용 → Plain DTO 사용 (BaseResponse 안 씀) |
장점:
✅ 방 생성, 목록 조회, 유저 목록 등은 HTTP 기반으로 안전하게 제공 가능
✅ 인증/인가 → Spring Security + OAuth2 등과 쉽게 연계 가능
✅ 클라이언트가 서버 상태를 쉽게 "초기화/조회" 가능 (ex: /api/chat/rooms 로 내 방 목록 가져오기 등)
✅ REST API는 로그 관리 / 테스트 / API 문서화 (Swagger) 등에서 매우 유리
단점:
❌ 채팅 메시지 송수신 흐름은 WebSocket으로 따로 관리해야 해서 코드가 분리됨
❌ 실시간 처리할 로직은 결국 WebSocket 쪽에서 또 중복될 수 있음
기능 | 구현 방식 |
---|---|
방 생성 / 삭제 / 목록 조회 | REST API |
실시간 메시지 송수신 | WebSocket (STOMP) |
채팅방 입장/퇴장 알림 | WebSocket (STOMP) or REST 혼용 가능 |
장점:
✅ 전체가 단일 통신 채널 (WebSocket) 로 통일 → 설계가 단순해짐
✅ 모바일/게임/고성능 서비스에서 선호 (연결 유지 상태에서 모든 기능 제공)
✅ 이벤트 기반 → 프론트-백 간 UX가 매끄러움
✅ WebSocket connection → session 을 활용해서 상태 관리 쉬움
단점:
❌ 방 목록 초기 조회도 WebSocket 이벤트로 해야 하므로 → 상태 동기화 코드가 늘어남
❌ 인증 처리 설계가 약간 복잡해짐 (토큰 전달 및 검증 등)
❌ 로그 기록 / API 문서화 어려움 → WebSocket은 Swagger 같은 도구로 문서화 어려움
❌ 서버 재시작 시 connection 재연결 필요 → 초기화/리커넥션 로직 고려 필요
조건 | 추천 방향 |
---|---|
아주 고성능 채팅 (게임/모바일/1:1 채팅) | WebSocket-only 설계 OK |
일반 서비스 채팅 (커뮤니티/그룹방/일반 Web 서비스) | REST + WebSocket 혼용이 유지보수성이 더 좋음 |
✅ 방 생성/조회/멤버 조회 → REST API
✅ 채팅 메시지 송수신/입장/퇴장 알림 → WebSocket
혼용 패턴을 사용하기로 했다!
가능은 한데:
REST API(@RestController
) 처럼 요청-응답 으로 들어오는 것이 아님 !
/pub
경로)클라이언트가 /pub/chat/message
같은 경로로 메시지를 보낼 때(HTTP POST 아님),
Spring은 @MessageMapping("/chat/message")
이 붙은 메서드를 호출함
이때 SimpMessagingTemplate이나 리턴값으로 다시 메시지를 브로드스트하거나 처리할 수 있다.
/sub
경로)messagingTemplate.convertAndSend("/sub/chat/room/{roomId}", dto)
이렇게 보내면/sub/chat/room/{roomId}
를 subscribe
(구독) 해 두었다가, 이 메시지를 받아서 렌더링함즉,
/pub/...
은 클라이언트가 “publish” 하는 엔드포인트(요청을 받는 곳),@MessageMapping
은 이 퍼블리시된 메시지를 처리하는 메서드,messagingTemplate.convertAndSend("/sub/...")
은 처리된 결과를 “subscribe” 중인 클라이언트에게 뿌려주는 곳입니다.REST 컨트롤러(/api/...
)와 완전히 별도의 메시징 레이어라고 생각해야 함!