Hoppa till huvudinnehållet
Version: 11.x

HTTP Batch Stream Link

Inofficiell Beta-översättning

Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →

httpBatchStreamLink är en terminerande länk som samlar en array av individuella tRPC-operationer till en enda HTTP-förfrågan som skickas till en enskild tRPC-procedur (motsvarande httpBatchLink), men väntar inte på att alla svar i batchen ska bli klara utan streamar svaren så fort någon data blir tillgänglig.

Alternativ

Alternativen är identiska med alternativen för httpBatchLink options.

Användning

All användning och alternativ är identiska med httpBatchLink.

notering

Om du behöver möjlighet att ändra/sätta svarshuvuden (inklusive cookies) från dina procedurer, se till att använda httpBatchLink istället! Detta beror på att httpBatchStreamLink inte stöder att sätta headers efter att strömmen har börjat. Läs mer.

Du kan importera och lägga till httpBatchStreamLink i links-arrayen så här:

client/index.ts
ts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';
import type { AppRouter } from '../server';
const client = createTRPCClient<AppRouter>({
links: [
httpBatchStreamLink({
url: 'http://localhost:3000',
}),
],
});
client/index.ts
ts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';
import type { AppRouter } from '../server';
const client = createTRPCClient<AppRouter>({
links: [
httpBatchStreamLink({
url: 'http://localhost:3000',
}),
],
});

Efter detta kan du utnyttja batchhantering genom att placera alla dina procedurer i ett Promise.all. Koden nedan genererar exakt en HTTP-förfrågan och på servern exakt en databasfråga:

ts
const somePosts = await Promise.all([
trpc.post.byId.query(1),
trpc.post.byId.query(2),
trpc.post.byId.query(3),
]);
ts
const somePosts = await Promise.all([
trpc.post.byId.query(1),
trpc.post.byId.query(2),
trpc.post.byId.query(3),
]);

Strömläge

När förfrågningar batchas väntar en vanlig httpBatchLink på att alla förfrågningar ska slutföras innan svaret skickas. Om du vill skicka svar så fort de blir klara kan du använda httpBatchStreamLink istället. Detta är användbart för långvariga förfrågningar.

client/index.ts
ts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';
import type { AppRouter } from '../server';
const client = createTRPCClient<AppRouter>({
links: [
httpBatchStreamLink({
url: 'http://localhost:3000',
}),
],
});
client/index.ts
ts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';
import type { AppRouter } from '../server';
const client = createTRPCClient<AppRouter>({
links: [
httpBatchStreamLink({
url: 'http://localhost:3000',
}),
],
});

Jämfört med en vanlig httpBatchLink kommer en httpBatchStreamLink att:

  • Skicka förfrågningar med en trpc-accept: application/jsonl-header

  • Skicka svaret med transfer-encoding: chunked och content-type: application/jsonl

  • Ta bort data-nyckeln från argumentobjektet som skickas till responseMeta (eftersom headers skickas före datan är tillgänglig i ett streamat svar)

Asynkrona generatorer och uppskjutna promises

Du kan prova detta på tRPC.io:s hemsida: https://trpc.io/?try=minimal#try-it-out

ts
// @filename: server.ts
import { publicProcedure, router } from './trpc';
 
const appRouter = router({
examples: {
iterable: publicProcedure.query(async function* () {
for (let i = 0; i < 3; i++) {
await new Promise((resolve) => setTimeout(resolve, 500));
yield i;
}
}),
},
});
 
export type AppRouter = typeof appRouter;
 
 
// @filename: client.ts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';
import type { AppRouter } from './server';
 
const trpc = createTRPCClient<AppRouter>({
links: [
httpBatchStreamLink({
url: 'http://localhost:3000',
}),
],
});
const iterable = await trpc.examples.iterable.query();
const iterable: AsyncIterable<number, never, unknown>
 
for await (const value of iterable) {
console.log('Iterable:', value);
const value: number
}
ts
// @filename: server.ts
import { publicProcedure, router } from './trpc';
 
const appRouter = router({
examples: {
iterable: publicProcedure.query(async function* () {
for (let i = 0; i < 3; i++) {
await new Promise((resolve) => setTimeout(resolve, 500));
yield i;
}
}),
},
});
 
export type AppRouter = typeof appRouter;
 
 
// @filename: client.ts
import { createTRPCClient, httpBatchStreamLink } from '@trpc/client';
import type { AppRouter } from './server';
 
const trpc = createTRPCClient<AppRouter>({
links: [
httpBatchStreamLink({
url: 'http://localhost:3000',
}),
],
});
const iterable = await trpc.examples.iterable.query();
const iterable: AsyncIterable<number, never, unknown>
 
for await (const value of iterable) {
console.log('Iterable:', value);
const value: number
}

Kompatibilitet (klientsida)

Webbläsare

Stödet i webbläsare bör vara identiskt med fetch-stödet.

Node.js / Deno

För runtime-miljöer utöver webbläsare måste fetch-implementationen stödja streaming, vilket innebär att svaret från await fetch(...) ska ha en body-egenskap av typen ReadableStream<Uint8Array> | NodeJS.ReadableStream, vilket betyder att:

  • antingen är response.body.getReader en funktion som returnerar ett ReadableStreamDefaultReader<Uint8Array>-objekt

  • eller så är response.body en Uint8Array-Buffer

Detta inkluderar stöd för undici, node-fetch, Node.js:s inbyggda fetch-implementation och WebAPI:s fetch-implementation (webbläsare).

React Native

Mottagande av strömmen förlitar sig på TextDecoder- och TextDecoderStream-API:er, som inte är tillgängliga i React Native. Notera att om din TextDecoderStream-polyfill inte automatiskt polyfillar ReadableStream och WritableStream måste dessa också polyfillas. Om du fortfarande vill aktivera streaming måste du polyfilla dessa.

Du måste också åsidosätta standard-fetchen i httpBatchStreamLink-konfigurationsalternativen. I exemplet nedan använder vi Expo fetch-paketet som fetch-implementation.

typescript
httpBatchStreamLink({
fetch: (url, opts) =>
fetch(url, {
...opts,
reactNative: { textStreaming: true },
}),
...restOfConfig,
});
typescript
httpBatchStreamLink({
fetch: (url, opts) =>
fetch(url, {
...opts,
reactNative: { textStreaming: true },
}),
...restOfConfig,
});

Kompatibilitet (serversida)

⚠️ För aws lambda stöds inte httpBatchStreamLink (kommer helt enkelt att fungera som en vanlig httpBatchLink). Det bör inte orsaka problem om det är aktiverat, men kommer inte att ha någon effekt.

⚠️ För cloudflare workers måste du aktivera ReadableStream-API:et via en funktionsflagga: streams_enable_constructors

Referens

Du kan se källkoden för denna länk på GitHub.

Konfigurera ett ping-alternativ för att hålla anslutningen vid liv

När du konfigurerar din rotkonfiguration kan du skicka med ett jsonl-alternativ för att ställa in ett ping-alternativ som håller anslutningen vid liv.

ts
import { initTRPC } from '@trpc/server';
const t = initTRPC.create({
jsonl: {
pingMs: 1000,
},
});
ts
import { initTRPC } from '@trpc/server';
const t = initTRPC.create({
jsonl: {
pingMs: 1000,
},
});