การสตรีม & อัปโหลด

callApiStream ใน Core อ่านการตอบสนอง NDJSON เป็น JSON ทีละบรรทัดและ emit ตามลำดับจาก Observable.


การใช้ callApiStream โดยตรงใน Core.

ใช้ callApiStream เมื่อเซิร์ฟเวอร์ส่ง NDJSON (JSON หนึ่งตัวต่อหนึ่งบรรทัด) หากไม่มี Accept header จะตั้งค่าเป็น application/x-ndjson เป็นค่าเริ่มต้น และหากต้องการ media type อื่นสามารถเขียนทับได้ด้วย headers ต่อคำขอ.

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 กับแต่ละบรรทัด คาดหวัง NDJSON ไม่ใช่รูปแบบ data: frame ของ SSE มาตรฐาน.

การสมัครสมาชิกและยกเลิกการสมัครสมาชิก Observable.

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

return () => subscription.unsubscribe();

การเรียก unsubscribe() จะยกเลิก reader ของ ReadableStream ภายในด้วย ให้ยกเลิกการสมัครสมาชิกใน React effect หรือการทำความสะอาดงาน.

เลือก: การใช้บริการ stream ที่สร้างขึ้น.

ในโครงการที่ใช้ OpenAPI generator สามารถทำให้บริการที่สร้างขึ้นเรียก callApiStream สำหรับ endpoint stream ได้ สามารถนำเข้าและสมัครสมาชิกในลักษณะเดียวกับบริการที่สร้างขึ้นทั่วไป.

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: PUT ไฟล์ไปยัง URL ที่กำหนด.

uploadFile.ts
ts
service.uploadFile({
  file,
  url: signedUploadUrl,
  headers: {
    "Content-Type": file.type || "application/octet-stream",
    "If-None-Match": "*",
  },
}).subscribe();