ARTICLE DETAIL

资讯详情

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

tRPC × AWS Lambda Adapter 实战指南:接入 API Gateway v1/v2、Lambda Function URL 与响应流式返回

tRPC × AWS Lambda Adapter 实战指南:接入 API Gateway v1/v2、Lambda Function URL 与响应流式返回 tRPC × AWS Lambda Adapter 实战指南接入 API Gateway v1/v2、Lambda Function URL 与响应流式返回【免费下载链接】trpc‍♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc导读本文以 tRPC 官方适配器trpc/server/adapters/aws-lambda为主线系统讲解如何将 tRPC Router 部署到 AWS Lambda覆盖 API Gateway REST APIv1 载荷格式、HTTP APIv2 载荷格式与 Lambda Function URL 三种接入方式并深入剖析awsLambdaStreamingRequestHandlerawslambda.streamifyResponse()的响应流式response streaming用法、maxBatchSize批量限制以及高频踩坑点。读完本文你将掌握从上下文注入、载荷格式区分到客户端httpBatchLink/httpLink正确选型的完整落地能力。本文对应仓库中的技能文档 packages/server/skills/adapter-aws-lambda/SKILL.md其内容主体源自官方适配器说明 www/docs/server/adapters/aws-lambda.md并配有 examples/lambda-api-gateway、examples/lambda-api-gateway-streaming 与 examples/lambda-url 三个可运行示例。适配器支持矩阵与原理AWS Lambda 适配器并非把 tRPC 当作独立 HTTP 服务监听端口而是导出一个由 API Gateway / Function URL 直接调用的 Lambda handler。请求事件event与运行时上下文context由 AWS 注入适配器负责完成「网关事件 → tRPC HTTP 请求」的解包以及「tRPC 响应 → 网关响应」的封包。它支持的三种接入场景接入方式载荷格式对应事件类型API Gateway REST APIv1.0APIGatewayProxyEventAPI Gateway HTTP APIv2.0可配置为 1.0APIGatewayProxyEventV2Lambda Function URL—APIGatewayProxyEventV2对应源码位于 packages/server/src/adapters/aws-lambda对外暴露两个核心入口awsLambdaRequestHandler标准缓冲式请求处理器awsLambdaStreamingRequestHandler流式响应处理器需配合awslambda.streamifyResponse()使用。最小可运行示例以下完整代码是官方技能文档中的标准起步模板可直接保存为server.tsimport { initTRPC } from trpc/server; import type { CreateAWSLambdaContextOptions } from trpc/server/adapters/aws-lambda; import { awsLambdaRequestHandler } from trpc/server/adapters/aws-lambda; import type { APIGatewayProxyEventV2 } from aws-lambda; import { z } from zod; const t initTRPC.create(); const appRouter t.router({ greet: t.procedure .input(z.object({ name: z.string() })) .query(({ input }) ({ greeting: Hello, ${input.name}! })), }); export type AppRouter typeof appRouter; const createContext ({ event, context, }: CreateAWSLambdaContextOptionsAPIGatewayProxyEventV2) ({ event, lambdaContext: context, }); export const handler awsLambdaRequestHandler({ router: appRouter, createContext, });部署完成后通过网关 URL 即可直接调用。以官方适配器文档为例若网关 event 暴露了查询 proceduregetUser调用形如GET https://execution-api-link/getUser?inputINPUT其中INPUT是 URI 编码的 JSON 字符串。也就是说tRPC 在 API Gateway 场景下把 procedure 映射为 URL 路径输入参数通过input查询参数传递。createContext把网关事件注入 tRPC 上下文createContext每个请求执行一次签名由CreateAWSLambdaContextOptionsT泛型参数决定。它解构出两个关键字段eventAPI Gateway / Function URL 传入的原始事件对象包含请求头、路径、authorizer 等contextLambda 运行时上下文函数名、内存、剩余时间等。你可以把鉴权信息塞进上下文例如从 API Gateway 的 authorizer claims 中读取用户import type { CreateAWSLambdaContextOptions } from trpc/server/adapters/aws-lambda; import { awsLambdaRequestHandler } from trpc/server/adapters/aws-lambda; import type { APIGatewayProxyEvent } from aws-lambda; import { appRouter } from ./router; const createContext ({ event, context, }: CreateAWSLambdaContextOptionsAPIGatewayProxyEvent) ({ user: event.requestContext.authorizer?.claims, }); export const handler awsLambdaRequestHandler({ router: appRouter, createContext, });仓库示例 examples/lambda-api-gateway/src/server.ts 展示了更贴近生产的一种上下文构造——把event、通过(event as { version?: string }).version判定的载荷版本以及请求头中的x-user一并注入function createContext({ event, context, }: CreateAWSLambdaContextOptionsAPIGatewayProxyEvent) { return { event: event, apiVersion: (event as { version?: string }).version ?? 1.0, user: event.headers[x-user], }; } type Context AwaitedReturnTypetypeof createContext; const t initTRPC.contextContext().create();注意这里使用了initTRPC.contextContext().create()将上下文类型显式接入 router随后 procedure 内即可通过opts.ctx.user读取请求头携带的用户标识。区分载荷格式版本 v1.0 与 v2.0这是 AWS Lambda 适配器最容易被忽视的细节。API Gateway 调用 Lambda 时存在两种事件数据格式版本 1.0→ 事件类型APIGatewayProxyEvent用于 REST API版本 2.0→ 事件类型APIGatewayProxyEventV2用于 HTTP APIHTTP API 也允许显式配置为 1.0。tRPC 的两个处理函数均同时支持两种事件类型关键在于给CreateAWSLambdaContextOptionsT传对泛型。官方文档给出如下类型推导写法便于在 createContext 中确定当前网关使用的版本import type { APIGatewayProxyEvent } from aws-lambda; import type { CreateAWSLambdaContextOptions } from trpc/server/adapters/aws-lambda; function createContext({ event, context, }: CreateAWSLambdaContextOptionsAPIGatewayProxyEvent) { // ... } // CreateAWSLambdaContextOptionsAPIGatewayProxyEvent 或 CreateAWSLambdaContextOptionsAPIGatewayProxyEventV2仓库中 examples/lambda-api-gateway/src/payloadFormatVersionClient.ts 展示了「一个 handler 同时服务 v1 REST API 与 v2 HTTP API」的经典拓扑由serverless.yml声明两个函数事件分别指向httpApi: *与http: { path: /{proxy}, method: any }再用两个 client不同 base URL分别验证两种载荷格式都能被正确处理。Lambda Function URL 场景若不希望引入 API Gateway可以直接给 Lambda 绑定 Function URL。Function URL 使用 v2 载荷格式事件因此上下文泛型应使用APIGatewayProxyEventV2。仓库示例 examples/lambda-url/src/server.ts 同时演示了普通 procedure、异步生成器流式 procedure 与延迟返回 procedure 三种形态可作为 Function URL 场景的完整参照。响应流式返回Response Streaming流式 handler 的签名差异awsLambdaStreamingRequestHandler的 handler 签名与默认 handler 不同除了常规的event与context参数流式 handler 内部还额外接收一个可写流参数responseStream。为了让 Lambda 按流式而非缓冲方式处理响应必须用awslambda.streamifyResponse()装饰整个 handler/// reference typesaws-lambda / import type { CreateAWSLambdaContextOptions } from trpc/server/adapters/aws-lambda; import { awsLambdaStreamingRequestHandler } from trpc/server/adapters/aws-lambda; import type { APIGatewayProxyEventV2 } from aws-lambda; import { appRouter } from ./router; const createContext ({ event, context, }: CreateAWSLambdaContextOptionsAPIGatewayProxyEventV2) ({}); export const handler awslambda.streamifyResponse( awsLambdaStreamingRequestHandler({ router: appRouter, createContext, }), );awslambda命名空间由 Lambda 执行环境自动提供无需也不应从 npm 安装若要获得类型提示可通过types/aws-lambda中的全局类型增强配合文件顶部的/// reference typesaws-lambda /指令引用。响应流式目前支持的接入面Lambda Function URLs 与 API Gateway REST APIs。对 REST API 集成还需在网关侧把集成配置为responseTransferMode: STREAM。定义一个可流式的 async generator procedure普通 query 返回的是完整结果而流式返回依赖async generatorprocedure——每yield一次客户端就能收到一段增量数据import { initTRPC } from trpc/server; const t initTRPC.create(); export const appRouter t.router({ countdown: t.procedure.query(async function* () { for (let i 10; i 0; i--) { await new Promise((resolve) setTimeout(resolve, 500)); yield i; } }), });仓库中的流式示例 examples/lambda-api-gateway-streaming/src/server.ts 更进一步在同一 router 内混合了三种 proceduregreet普通 queryiterableasync generator每 500ms 产出一个递增数字deferred根据输入wait参数人为延迟后返回。这说明流式 handler 与普通 handler 共用同一套 router单个函数可以同时承担「即时响应」与「流式响应」两种能力。客户端如何消费流服务端开启流式之后客户端需要使用支持流式读取的 link。技能文档明确指出与httpBatchStreamLink配对使用即客户端用httpBatchStreamLink而非httpBatchLink发起请求才能把流式响应逐段呈现给上层。用 maxBatchSize 限制请求批量大小tRPC 客户端会把同批次内的多个调用合并成一个 HTTP 请求如路径形如getUser,createUser服务端默认接受批量请求。若网关路径或业务对单次批量数量敏感可显式限制import { awsLambdaRequestHandler } from trpc/server/adapters/aws-lambda; import { appRouter } from ./router; export const handler awsLambdaRequestHandler({ router: appRouter, createContext, maxBatchSize: 10, });单请求携带超过maxBatchSize个操作时服务端以400 Bad Request拒绝为避免无谓报错客户端httpBatchLink/httpBatchStreamLink上的maxItems应设置为与服务端相同的数值。高频踩坑Common Mistakes坑 1高危在「每 procedure 一个 API Gateway 资源」的架构里误用 httpBatchLink// 错误示范 // API Gateway 为每个 procedure 单独建资源例如 /getUser、/createUser import { httpBatchLink } from trpc/client; httpBatchLink({ url: https://api.example.com }); // 批量请求打到 /getUser,createUser → 404httpBatchLink会把多个 procedure 名用逗号拼进 URL 路径。当网关按 procedure 逐一配置资源时getUser,createUser这种合并路径匹配不到任何资源直接 404。正确做法二选一import { httpBatchLink, httpLink } from trpc/client; // 方案 A网关只建一个 catch-all 资源如 /{proxy}可继续使用批量 httpBatchLink({ url: https://api.example.com }); // 方案 B每 procedure 一个资源的场景改用 httpLink放弃批量 httpLink({ url: https://api.example.com });仓库 examples/lambda-api-gateway/serverless.yml 就是方案 A 的标准配置HTTP API 使用events: - httpApi: *REST API 使用path: /{proxy}配合method: any保证任意路径都能路由到同一个 handler从而让httpBatchLink正常工作。坑 2高危流式 handler 漏包 streamifyResponse// 错误示范 export const handler awsLambdaStreamingRequestHandler({ router: appRouter, createContext, });// 正确示范 export const handler awslambda.streamifyResponse( awsLambdaStreamingRequestHandler({ router: appRouter, createContext, }), );awsLambdaStreamingRequestHandler必须被awslambda.streamifyResponse()包裹才能真正开启 Lambda 响应流式模式否则 Lambda 会把它当作标准缓冲式 handler 处理响应将被整体缓冲后再返回流式语义失效。同理也不要画蛇添足地对标准awsLambdaRequestHandler使用streamifyResponse。完整落地路线图安装依赖在 Lambda 函数项目中加入trpc/server以及配套校验库如zod客户端侧安装trpc/client。注意运行时版本需与所用 API Gateway / Lambda 配置兼容。定义 Router用initTRPC.create()或initTRPC.contextContext().create()声明 procedures并export type AppRouter typeof appRouter供客户端复用类型。编写 createContext以CreateAWSLambdaContextOptionsAPIGatewayProxyEvent或APIGatewayProxyEventV2约束签名把event、context、鉴权 claims、自定义头等放入上下文。导出 handler选择awsLambdaRequestHandler普通或awslambda.streamifyResponse(awsLambdaStreamingRequestHandler({...}))流式。配置网关REST API 使用/下的{proxy}兜底路由并转发所有方法与任意路径HTTP API 使用通配路由REST API 流式需开启responseTransferMode: STREAM。客户端接入单资源 catch-all 路由可用httpBatchLink需要消费流式 async generator 时改用httpBatchStreamLink每 procedure 独立资源则退化为httpLink并让maxItems与服务端maxBatchSize保持一致。本地联调可参考 examples/lambda-api-gateway/package.json 引入serverless-esbuild与serverless-offline在本地模拟网关事件、用 examples/lambda-api-gateway/src/client.ts 验证链路后再部署到云端。关联技能与延伸阅读本文所属的技能体系位于 packages/server/skills/adapter-aws-lambda编排文件 packages/server/skills/adapter-aws-lambda/SKILL.md 中还标注了以下前置与相邻技能可按需串联学习server-setupinitTRPC.create()、router/procedure 定义与 context 基础server-setup 技能adapter-fetch面向 edge/serverless 运行时、基于 Fetch API 的替代适配方案adapter-fetch 技能linkshttpBatchLink与httpLink在 API Gateway 路由约束下的取舍客户端 links 目录。更完整的适配器背景知识载荷格式版本、部署后的调用 URI 表、示例应用索引可查阅官方文档 www/docs/server/adapters/aws-lambda.md三个贴近生产的可运行示例分别在 examples/lambda-api-gateway、examples/lambda-api-gateway-streaming 与 examples/lambda-url。【免费下载链接】trpc‍♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表