HTTP 批处理流式链接
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
httpBatchStreamLink 是一个终止链接,它将多个独立的 tRPC 操作批处理成单个 HTTP 请求发送到单个 tRPC 过程(等同于 httpBatchLink),但不会等待批处理中所有响应准备完成,而是在任何数据可用时立即流式传输响应。
选项
配置选项与 httpBatchLink options 完全相同。
用法
所有用法和选项均与
httpBatchLink完全相同。
如果需要在过程中修改/设置响应头(包括 cookies),请务必改用 httpBatchLink!这是因为 httpBatchStreamLink 不支持在流启动后设置响应头。了解更多。
您可以通过以下方式导入并将 httpBatchStreamLink 添加到 links 数组:
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
之后,您可以通过将所有过程放入 Promise.all 来利用批处理功能。以下代码将产生仅一次 HTTP 请求,在服务器端执行仅一次数据库查询:
tsconst somePosts = await Promise.all([trpc.post.byId.query(1),trpc.post.byId.query(2),trpc.post.byId.query(3),]);
tsconst somePosts = await Promise.all([trpc.post.byId.query(1),trpc.post.byId.query(2),trpc.post.byId.query(3),]);
流式模式
当批量处理请求时,常规 httpBatchLink 的行为是等待所有请求完成后再发送响应。如果您希望在响应就绪时立即发送,可以改用 httpBatchStreamLink。这对于长时间运行的请求非常有用。
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
client/index.tstsimport { createTRPCClient, httpBatchStreamLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpBatchStreamLink({url: 'http://localhost:3000',}),],});
相比常规 httpBatchLink,httpBatchStreamLink 将:
-
在请求头中添加
trpc-accept: application/jsonl -
在响应头中添加
transfer-encoding: chunked和content-type: application/jsonl -
从传递给
responseMeta的参数对象中移除data键(因为使用流式响应时,标头在数据可用前就已发送)
异步生成器与延迟 Promise
您可以在 tRPC.io 首页体验此功能:https://trpc.io/?try=minimal#try-it-out
ts// @filename: server.tsimport {publicProcedure ,router } from './trpc';constappRouter =router ({examples : {iterable :publicProcedure .query (async function* () {for (leti = 0;i < 3;i ++) {await newPromise ((resolve ) =>setTimeout (resolve , 500));yieldi ;}}),},});export typeAppRouter = typeofappRouter ;// @filename: client.tsimport {createTRPCClient ,httpBatchStreamLink } from '@trpc/client';import type {AppRouter } from './server';consttrpc =createTRPCClient <AppRouter >({links : [httpBatchStreamLink ({url : 'http://localhost:3000',}),],});constiterable = awaittrpc .examples .iterable .query ();for await (constvalue ofiterable ) {console .log ('Iterable:',value );}
ts// @filename: server.tsimport {publicProcedure ,router } from './trpc';constappRouter =router ({examples : {iterable :publicProcedure .query (async function* () {for (leti = 0;i < 3;i ++) {await newPromise ((resolve ) =>setTimeout (resolve , 500));yieldi ;}}),},});export typeAppRouter = typeofappRouter ;// @filename: client.tsimport {createTRPCClient ,httpBatchStreamLink } from '@trpc/client';import type {AppRouter } from './server';consttrpc =createTRPCClient <AppRouter >({links : [httpBatchStreamLink ({url : 'http://localhost:3000',}),],});constiterable = awaittrpc .examples .iterable .query ();for await (constvalue ofiterable ) {console .log ('Iterable:',value );}
兼容性(客户端)
浏览器
浏览器支持应与 fetch 支持范围相同。
Node.js / Deno
对于非浏览器运行时,fetch 实现需支持流式传输,即通过 await fetch(...) 获取的响应应具有类型为 ReadableStream<Uint8Array> | NodeJS.ReadableStream 的 body 属性,这意味着:
-
response.body.getReader是返回ReadableStreamDefaultReader<Uint8Array>对象的函数 -
或
response.body是Uint8Array类型的Buffer
这包括对 undici、node-fetch、原生 Node.js fetch 实现和 WebAPI fetch 实现(浏览器)的支持。
React Native
接收流依赖于 TextDecoder 和 TextDecoderStream API,而 React Native 不提供这些 API。请注意:如果您的 TextDecoderStream 垫片未自动填充 ReadableStream 和 WritableStream,则需额外填充这些对象。若仍需启用流式传输,必须自行填充这些 API。
您还需要在 httpBatchStreamLink 的配置选项中覆盖默认的 fetch 实现。在下面的示例中,我们将使用 Expo fetch 包作为 fetch 的实现方案。
typescripthttpBatchStreamLink({fetch: (url, opts) =>fetch(url, {...opts,reactNative: { textStreaming: true },}),...restOfConfig,});
typescripthttpBatchStreamLink({fetch: (url, opts) =>fetch(url, {...opts,reactNative: { textStreaming: true },}),...restOfConfig,});
兼容性(服务端)
⚠️ 对于 AWS Lambda,
httpBatchStreamLink不受支持(行为等同于常规httpBatchLink)。启用后不会导致功能异常,但不会产生任何效果。
⚠️ 在 Cloudflare Workers 中,需通过特性标志启用
ReadableStreamAPI:streams_enable_constructors
参考文档
您可以在 GitHub 查看此链接的源代码。
配置 ping 选项保持连接活跃
在设置根配置时,可以传入 jsonl 选项来配置 ping 机制以保持连接活跃。
tsimport { initTRPC } from '@trpc/server';const t = initTRPC.create({jsonl: {pingMs: 1000,},});
tsimport { initTRPC } from '@trpc/server';const t = initTRPC.create({jsonl: {pingMs: 1000,},});