ストリーミング & アップロード

CoreのcallApiStreamはNDJSON応答を行単位のJSONとして読み取り、Observableから順番にemitします。


CoreでcallApiStreamを直接使用

サーバーがNDJSON(1行にJSON1つ)を返すときにcallApiStreamを使用します。Acceptヘッダーがない場合はapplication/x-ndjsonをデフォルトとして設定し、他のメディアタイプが必要な場合はリクエストごとのヘッダーで上書きできます。

ts
export const streamEvents = () => {
  return client.callApiStream<{
    eventName: string;
    content: unknown;
  }>({
    url: "/api/event/stream",
    method: "get",
    // headers: { Accept: "application/x-ndjson" },
  });
};

NDJSON応答形式

text
{"status":"STARTED","progress":0}
{"status":"PROGRESS","progress":35}
{"status":"PROGRESS","progress":80}
{"status":"DONE","progress":100}

callApiStreamは改行を基準に応答を分割し、各行をJSON.parseします。標準SSEのdata:フレーム形式ではなくNDJSONを期待します。

Observableの購読と解除

tsx
const subscription = streamEvents().subscribe({
  next: (event) => {
    setProgress(event.content);
  },
  error: (error) => {
    setErrorMessage(error.message);
  },
  complete: () => {
    setRunning(false);
  },
});

return () => subscription.unsubscribe();

unsubscribe()すると内部のReadableStreamリーダーもキャンセルされます。Reactのエフェクトや作業のクリーンアップで購読を解除してください。

オプション: 生成されたストリームサービスの使用

OpenAPIジェネレーターを使用するプロジェクトでは、ストリームエンドポイントに対して生成されたサービスがcallApiStreamを呼び出すようにできます。画面では通常の生成サービスと同じ方法でインポートしてsubscribeします。

tsx
const subscription = jobProgress({
  path: { jobId },
}).subscribe({
  next: (event) => {
    setProgress(event.progress || 0);
  },
  error: (error) => {
    setErrorMessage(error.message);
  },
  complete: () => {
    setRunning(false);
  },
});

return () => subscription.unsubscribe();

uploadFile: 指定URLにファイルをPUT

uploadFile.ts
ts
service.uploadFile({
  file,
  url: signedUploadUrl,
  headers: {
    "Content-Type": file.type || "application/octet-stream",
    "If-None-Match": "*",
  },
}).subscribe();
© 2026 Byeolnaerim. 無断転載を禁じます。紹介プライバシーポリシー