본문 바로가기
C.W.K.
Stream
Lesson 02 of 04 · published

WebSocket 말고 REST + SSE

~11 min · rest-sse, websocket, transport, producer-leg

Level 0식은 초고
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"트랜스포트는 트래픽 모양을 보고 골라. Rekindle 은 백엔드가 계속 읽어야 할 게 없으니까 순수 HTTP 가 이겨."

트랜스포트를 트래픽에 맞춰

WebSocket 은 계속 열려 있는 양방향 파이프야. 강력하지만 순수 HTTP 보다 굴리기도 따지기도 복잡해. 물어야 할 건 '어느 쪽이 더 그럴듯한가' 가 아니라 '트래픽 모양이 어떤가' 지. Rekindle 의 트래픽은 단순해. 메시지를 보내면 스트림으로 응답이 오고, 텍스트를 선택하면 재작성 요청이 한 번 나가. 에디터에서 백엔드로 계속 흘러가는 건 없어. 그래서 Rekindle 은 bind 는 REST 로, 스트림은 SSE 로 처리하고 WebSocket 은 통째로 건너뛰어. cwkBonfire 가 쓰는 embed 모델 그대로야.

왜 Cinder 는 WebSocket 이 필요하고 Rekindle 은 아닌가

Cinder 와 비교해보면 이 레슨이 다 설명돼. Cinder 는 Photoshop 옆에 얹혀 가는데, 그 UXP 플러그인이 백엔드가 읽어야 할 상태를 계속 밀어 올려. 진짜 producer leg 이 있는 거고, 상시로 위로 흐르는 그 흐름이 지속 소켓을 정당화하지. Rekindle 한텐 producer leg 이 없어. 문서 맥락은 매 턴 한 번씩 실어 보내는 거지 계속 흐르는 스트림이 아니고, 백엔드가 계속 읽고 있어야 할 라이브 피드도 없거든. 같은 가족인데 트래픽 모양이 다르니 트랜스포트도 다른 게 맞는 거야.

표면      상류 흐름                     트랜스포트
-------   ---------------------------   ----------------------
Cinder    Photoshop 이 계속 push        WebSocket (producer leg)
Rekindle  메시지, 그다음 응답           REST (bind) + SSE (스트림)

# 지속 producer 없음 -> WebSocket 없음. 순수 HTTP 가 맞는 크기.

bind 는 REST, 스트림은 SSE

구체적으로 보면 이래. REST 호출이 문서를 대화에 bind 하고 턴을 보내. 응답은 SSE 로 토큰 단위로 흘러 들어오고, cwkPippa 자기 채팅이 하는 것과 똑같아. CMD+K 는 더 단순해서 재작성 결과를 돌려주는 POST 한 번이면 끝이고. 둘 다 순수 HTTP 에 딱 맞아. 필요한 만큼만 작은 트랜스포트를 고르는 건 소심한 게 아니야. 필요한 만큼만 최소로 빌리고 (트랙 3) 기존 엔진을 재사용하는 (트랙 5) 그 규율과 같은 얘기지. 요청하고 스트림 받는 것으로 충분한 트래픽에 지속 소켓을 굴리지 마.

Code

bind 와 전송은 REST, 응답 스트림은 SSE·typescript
// 순수 HTTP 로 bind 하고 턴을 보내. 지속 소켓은 없어.
const res = await fetch(`/api/chat`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ conversationId, message, hostContext }),
});

// 응답은 Server-Sent Events 로 토큰 단위로 흘러 들어와.
// cwkPippa 자기 채팅이 쓰는 그 스트리밍이야.
for await (const event of readSSE(res.body)) {
  appendToken(event.data);
}

// CMD+K 는 더 단순해. 재작성 하나를 돌려주는 POST 한 번.
// 위로 스트림하는 게 없으니 여기서 WebSocket 은 쓸 데가 없어.

External links

Exercise

기능 셋을 놓고 각각 어떤 트랜스포트가 필요한지 정해봐. 커서를 실시간으로 공유하는 협업 뷰, 응답이 스트림으로 오는 채팅, 그리고 한 번 누르면 끝인 '이거 요약해' 버튼. 어느 것이 상시로 위로 흐르는 producer leg 을 가져서 WebSocket 을 정당화하고, 나머지 둘은 왜 REST 와 SSE 로 충분한지 짚어봐. producer leg 테스트 하나로 셋이 다 정해지는 걸 확인해.
Hint
커서 공유는 위치를 계속 위로 올려보내니까 WebSocket 이야. 스트림 채팅은 요청하고 아래로 스트림을 받으니까 SSE 고. 한 번짜리 요약은 요청 하나에 응답 하나니까 순수 REST 지. 첫 번째만 producer leg 이 있고 나머지 둘은 소켓이 필요 없어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.