ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

tRPC 批量请求 URL 过长时如何用 methodOverride 将所有 RPC 调用改为 POST

tRPC 批量请求 URL 过长时如何用 methodOverride 将所有 RPC 调用改为 POST 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),仅供参考
返回列表