ストリーミング & アップロード
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
tsservice.uploadFile({
file,
url: signedUploadUrl,
headers: {
"Content-Type": file.type || "application/octet-stream",
"If-None-Match": "*",
},
}).subscribe();