Stream
Vous pouvez renvoyer un flux applicatif continu avec ResponseContract.stream pour des chunks binaires, ou ResponseContract.streamText pour des chunks texte.
ts
import { ResponseContract, useRouteBuilder } from "@duplojs/http";
import { DPE, sleep } from "@duplojs/utils";
useRouteBuilder("GET", "/binary-stream")
.handler(
ResponseContract.stream(
"binary-stream",
DPE.number(),
),
(__, { streamResponse }) => streamResponse(
"binary-stream",
async({ send }) => {
await send(12);
await sleep(500);
await send(20);
},
),
);
useRouteBuilder("POST", "/text-stream")
.extract({
body: {
value: DPE.string(),
},
})
.handler(
ResponseContract.streamText("text-stream"),
({ value }, { streamTextResponse }) => streamTextResponse(
"text-stream",
async({ send }) => {
await send("hello");
await sleep(500);
await send(` ${value}`);
},
),
);stream est adapté quand vous voulez pousser des chunks opaques côté client. streamText est plus pratique quand vous voulez consommer directement des chaînes.
Consommer le flux côté client
Le client détecte automatiquement ce type de réponse et retourne un objet itérable enrichi avec des hooks onStream.
ts
import { createHttpClient } from "@duplojs/http/client";
import { type Routes } from "./types";
const client = createHttpClient<Routes>({
baseUrl: "http://localhost:1506",
});
const binaryResponse = await client
.get("/binary-stream")
.iWantInformationOrThrow("binary-stream");
binaryResponse.onStream("receiveData", (chunk) => {
});
for await (const chunk of binaryResponse) {
// ...
}
const textResponse = await client
.post(
"/text-stream",
{ body: { value: "world" } },
)
.iWantInformationOrThrow("text-stream");
textResponse.onStream("receiveData", (chunk) => {
});
void textResponse.consumeStream();Pour consommer le flux, vous pouvez soit itérer sur la réponse avec for await...of, soit appeler consumeStream(). L'événement receiveData reçoit le type de chunk adapté au contrat client généré.
