Skip to main content
POST
https://bithumb-saju.vercel.app
/
api
/
daily-fortune-stream
일일 운세 스트리밍
curl --request POST \
  --url https://bithumb-saju.vercel.app/api/daily-fortune-stream \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <api-key>' \
  --data '
{
  "saju": {},
  "userName": "<string>",
  "date": "<string>",
  "model": "<string>"
}
'
Server-Sent Events(SSE)를 통해 운세를 실시간으로 스트리밍합니다. AI 응답이 생성되는 대로 클라이언트에 전달되어, 사용자에게 더 빠른 피드백을 제공할 수 있습니다.

Request Body

saju
SajuResult
required
클라이언트에서 계산한 사주 데이터 객체입니다.
userName
string
required
사용자 이름입니다.
date
string
required
운세를 볼 날짜입니다. YYYY-MM-DD 형식입니다.
model
string
default:"haiku"
사용할 AI 모델입니다.

Response

성공

SSE 스트림이 시작됩니다. Content-Type은 text/event-stream입니다.

이벤트 형식

data: {"chunk": "오늘은 "}

data: {"chunk": "투자에 "}

data: {"chunk": "좋은 날입니다."}

data: {"done": true, "fortune": {...}}

요청 예시

const response = await fetch('/api/daily-fortune-stream', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    saju,
    userName: '김철수',
    date: '2025-01-16',
    model: 'haiku'
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  const lines = chunk.split('\n');

  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6));

      if (data.chunk) {
        // 텍스트 청크 - UI에 추가
        console.log(data.chunk);
      }

      if (data.done) {
        // 스트리밍 완료 - 전체 데이터 사용 가능
        console.log('완료:', data.fortune);
      }
    }
  }
}

SSE 이벤트 구조

청크 이벤트

AI가 텍스트를 생성할 때마다 전송됩니다.
{
  "chunk": "오늘은 투자에 "
}

완료 이벤트

스트리밍이 완료되면 전체 운세 데이터와 함께 전송됩니다.
{
  "done": true,
  "fortune": {
    "todayFortune": {
      "score": 78,
      "overallAnalysis": "...",
      "actionItems": [...]
    },
    "investmentFortune": {...}
  }
}

에러 처리

스트리밍 중 에러가 발생하면 에러 이벤트가 전송됩니다.
{
  "error": true,
  "message": "AI model timeout"
}
// 에러 처리 예시
for (const line of lines) {
  if (line.startsWith('data: ')) {
    const data = JSON.parse(line.slice(6));

    if (data.error) {
      console.error('스트리밍 에러:', data.message);
      // 폴백: 일반 API 호출
      const fallback = await fetch('/api/daily-fortune', {...});
    }
  }
}
스트리밍은 긴 응답에 특히 유용합니다. 짧은 응답(character, tendency 등)은 일반 API를 사용하는 것이 더 효율적입니다.