
tRPC 批量请求 URL 过长时如何用 methodOverride 将所有 RPC 调用改为 POST【免费下载链接】trpc♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc使用httpBatchLink的 tRPC 客户端会把同一时刻的多个并行调用合并进一个 HTTP 请求。对于 query合并后的输入参数JSON 序列化会拼在 URL 的input查询参数里批处理还会额外带上batch1。当批量里的操作较多或输入较大时URL 会随之膨胀触发413 Payload Too Large、414 URI Too Long、404 Not Found这类 HTTP 错误。tRPC 提供的解决方式是给 link 设置methodOverride: POST让所有 RPC 调用query 和 mutation都改走 POST输入随之从 URL 移入请求体。本文给出客户端与服务端两侧的配置以及如何验证它已生效。先确认错误现象批处理的 URL 里装了哪些东西按 HTTP RPC Specification 的定义tRPC 的方法映射与批处理格式是HTTP Method对应调用说明GET.query()输入以 JSON 序列化后放在 query param例如myQuery?input${encodeURIComponent(JSON.stringify(input))}POST.mutation()输入放在 POST body批处理时同一 HTTP method 的并行调用会被合并为一个请求各 procedure 的路径名用逗号,拼在pathname里输入参数放在名为input的 query param 中形状为Recordnumber, unknown同时必须带batch1查询参数若各调用返回状态不同响应会返回207 Multi-Status。也就是说query 越多、输入越大?batch1input...这一串就越长。当它导致请求失败时HTTP Batch Link 文档 给出的两个方向是用maxURLLength限制单批规模自动拆成多个请求或者用methodOverride: POST让输入不再走 URL。本文主路径是后者。客户端给 batch link 设置 methodOverride: POSTmethodOverride是 HTTPLinkOptions 定义的选项唯一可取值为POST/** * Send all requests as POSTS requests regardless of the procedure type * The server must separately allow overriding the method. */ methodOverride?: POST;在客户端创建 client 时把它加到httpBatchLink的 options 里来自 httpBatchLink 文档 的示例import { createTRPCClient, httpBatchLink } from trpc/client; import type { AppRouter } from ./server; const client createTRPCClientAppRouter({ links: [ httpBatchLink({ url: http://localhost:3000, methodOverride: POST, // alternatively, you can make all RPC-calls to be called with POST }), ], });设置后所有 query 和 mutation 都会以 POST 请求发往 tRPC Server。客户端的 URL 构造逻辑也印证了这一点httpUtils.ts 中只有methodOverride ! POST时才会把input...追加到 URL同时请求体body会携带 JSON 序列化的输入。因此启用后URL 只剩路径和batch1不再有长度问题。如果你的客户端没有用批处理rpc.md 中httpLink的用法同样支持这个选项import { createTRPCClient, httpLink } from trpc/client; import type { AppRouter } from ./server; // The client can then specify which HTTP method to use for all queries/mutations const client createTRPCClientAppRouter({ links: [ httpLink({ url: http://localhost:3000, methodOverride: POST, // all queries and mutations will be sent to the tRPC Server as POST requests. }), ], });服务端必须单独开启 allowMethodOverride只改客户端是不够的。httpLink的选项说明里明确写着 “The server must separately allow overriding the method”服务端必须显式允许客户端覆写 HTTP method。rpc.md 给出的 standalone 适配器示例import { initTRPC } from trpc/server; import { createHTTPHandler } from trpc/server/adapters/standalone; const t initTRPC.create(); const router t.router({}); // Your server must separately allow the client to override the HTTP method const handler createHTTPHandler({ router: router, allowMethodOverride: true, });两点来自源码的补充allowMethodOverride定义在共用的 handler options 类型中types.ts因此其他适配器的createHTTP*入口如 httpBatchLink 文档 中展示的 standalonecreateHTTPServer以 options 传入maxBatchSize等参数同样可以传入该选项在 resolveResponse.ts 中覆写仅在请求本身就是POST时生效const allowMethodOverride (opts.allowMethodOverride ?? false) req.method POST。即服务端只把“POST 打到 query procedure”这类原本不允许的组合放行。验证配置是否生效仓库中的 methodOverride.test.ts 提供了三个可直接对照的验证场景均使用qquery与mmutation两个 procedure1. 单个 query 以 POST 发送后能正常返回// 客户端 linkOptions: { methodOverride: POST }服务端 allowMethodOverride: true expect( await t.client.q.query({ who: test1 }), ).toBe(hello test1);2. 批处理场景下query 与 mutation 混合的Promise.all全部以 POST 走通测试中的期望输出文档示例// 客户端使用 httpBatchLink 且 linkOptions: { methodOverride: POST }服务端 allowMethodOverride: true expect( await Promise.all([ t.client.q.query({ who: test1 }), t.client.q.query({ who: test2 }), t.client.m.mutate({ who: test3 }), ]), ).toMatchInlineSnapshot( Array [ hello test1, hello test2, hello test3, ] );3. 反向验证服务端未开启allowMethodOverride时POST 打到 query procedure 会被拒绝。该场景下客户端收到的错误信息为测试中的期望输出[TRPCClientError: Unsupported POST-request to query procedure at path q]如果你在启用methodOverride: POST后看到了这条Unsupported POST-request to query procedure错误说明服务端漏配了allowMethodOverride: true回到上一步检查即可。限制与可选分支选项取值固定methodOverride只接受POST类型上不存在其他取值。替代方案maxURLLength如果不想改请求方法可以给httpBatchLink配置maxURLLength默认Infinity它会限制单次批处理的 URL 长度上限超限的操作自动拆分成多个请求。例如文档中给出maxURLLength: 2083注释为 “a suitable size”的示例。与maxItems/maxBatchSize配合maxItems限制客户端单个批处理的调用数应保持小于或等于服务端的maxBatchSize超过服务端maxBatchSize的请求会被400 Bad Request拒绝。这两项限制的是批的条数不解决单条输入过大导致的 URL 过长问题与methodOverride解决的是同一问题的不同侧面可按需同时使用。验证路径回到具体结果客户端请求 URL 不再携带input参数、Promise.all批调用按测试期望返回数据即为配置成功若出现Unsupported POST-request to query procedure错误则为服务端未开启allowMethodOverride。【免费下载链接】trpc♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考