如何借助SST自动生成关联API Gateway的AWS Lambda函数OpenAPI规范?
自动生成SST项目的OpenAPI规范方案
方法一:利用SST Api类的内置能力导出OpenAPI
SST的Api构造器基于AWS CDK的RestApi,可以直接通过配置或部署钩子实现OpenAPI规范的导出。
- 部署时自动生成并存储规范文件
在SST的Stack类中,创建Api实例后,添加自定义资源调用API Gateway的GetExport接口导出规范:
import { Stack, Api, CustomResource } from "sst/constructs"; import { aws_apigateway as apigw } from "aws-cdk-lib"; import { GetExportCommand, ApiGatewayClient } from "@aws-sdk/client-api-gateway"; // 自定义资源处理Lambda(可放在单独文件) const exportHandler = async (event) => { const client = new ApiGatewayClient({}); const command = new GetExportCommand({ restApiId: event.ResourceProperties.RestApiId, stageName: event.ResourceProperties.StageName, exportType: "swagger", }); const response = await client.send(command); // 可将结果上传到S3或写入本地文件(本地开发场景) return { PhysicalResourceId: "OpenApiExport" }; }; export default class MyStack extends Stack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); const api = new Api(this, "MyApi", { routes: { "GET /users/{id}": "packages/functions/src/getUser.handler", "POST /users": "packages/functions/src/createUser.handler", }, }); // 添加自定义资源触发导出 new CustomResource(this, "ExportOpenApi", { serviceToken: /* 注册上述exportHandler为Lambda的ARN */, properties: { RestApiId: api.restApiId, StageName: api.stage, }, }); } }
- 本地开发时快速导出
启动SST本地开发服务后,从控制台输出中获取本地API的ID,执行以下AWS CLI命令导出:
aws apigateway get-export --rest-api-id <LOCAL_API_ID> --stage-name dev --export-type swagger openapi.json
方法二:结合TypeScript类型与ts-openapi自动生成
使用ts-openapi工具,基于Lambda函数的输入输出类型定义,自动生成规范后关联到SST的Api路由。
- 安装依赖
npm install ts-openapi --save-dev
- 在Lambda函数中定义API元数据
以createUser.ts为例:
import { OpenApi, Types } from "ts-openapi"; const openApi = new OpenApi( "1.0.0", "User Management API", "API for user CRUD operations", "dev@example.com" ); // 定义请求体Schema const userCreateSchema = Types.Object({ firstName: Types.String({ required: true, description: "User's first name" }), lastName: Types.String({ required: true, description: "User's last name" }), }); // 注册POST /users接口信息 openApi.addPath( "/users", { post: { summary: "Create a new user", requestBody: { content: { "application/json": { schema: userCreateSchema }, }, }, responses: { 201: { description: "User created successfully", content: { "application/json": { schema: Types.Object({ id: Types.String({ description: "User ID" }), ...userCreateSchema.properties, }), }, }, }, }, }, }, true ); // 导出完整规范 export const openApiSpec = openApi.generateJson();
- 在SST Stack中关联规范
编写脚本收集所有Lambda的OpenAPI元数据并合并,之后在Stack中引用:
import { readFileSync } from "fs"; import { Stack, Api } from "sst/constructs"; export default class MyStack extends Stack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); // 读取预先生成的OpenAPI规范文件 const openApiSpec = JSON.parse(readFileSync("./packages/functions/openapi.json", "utf-8")); const api = new Api(this, "MyApi", { definition: openApiSpec, routes: { "POST /users": "packages/functions/src/createUser.handler", "GET /users/{id}": "packages/functions/src/getUser.handler", }, }); } }
方法三:SST + Tsoa集成优化方案
如果你之前尝试过Tsoa,可以按以下步骤集成:
- 配置
tsoa.json指定规范输出路径,运行tsoa spec生成swagger.json。 - 在SST Stack中直接将该文件作为Api的
definition参数,手动(或通过脚本自动)映射规范中的路由到对应Lambda函数。
注意事项
- 确保Lambda函数的输入输出类型与OpenAPI规范定义保持一致,避免出现接口不匹配问题。
- 本地开发时,可结合SST的
sst start实时生成规范,方便调试接口。 - 若需将规范暴露给前端,可在SST中创建S3存储桶上传规范文件,或通过Lambda代理提供访问。
内容的提问来源于stack exchange,提问作者JaVaBoy
相关产品推荐
相关产品推荐

