如何使用AWS CDK在实例化API Gateway时向OpenAPI spec传参
问题
AWS CDK支持通过本地OpenAPI规范文件实例化API Gateway,示例代码如下:
String specFilePath = "spec_file.yaml" Asset openApiAsset = Asset.Builder.create(..., "assetId").path(specFilePath).build() Map<String, String> transformMap = Map.of("Location", openAPIAsset.getS3ObjectUrl) IResolvable data = Fn.transform("AWS::Include", transformMap) InlineApiDefinition apiDefinition = ApiDefinition.fromInline(data) SpecRestApi specRestApi = SpecRestApi.Builder.create(...).apiDefinition(apiDefinition)...
请问如何在运行时将变量替换到该规范文件中?即能否在spec_file.yaml中设置类似${fill_in_at_runtime}的占位符,并在实例化ApiDefinition时传入对应值,例如类似如下形式:
InlineApiDefinition apiDefinition = ApiDefinition.fromInline(data).replace("fill_in_at_runtime", "42")
解决方案
方法1:本地文件读取后直接替换占位符
适合简单静态变量替换,先读取本地OpenAPI文件内容,替换占位符后再传入CDK:
// 读取本地spec文件内容 String specContent = Files.readString(Paths.get(specFilePath)); // 替换目标占位符 specContent = specContent.replace("${fill_in_at_runtime}", "42"); // 创建ApiDefinition InlineApiDefinition apiDefinition = ApiDefinition.fromInline(specContent); SpecRestApi specRestApi = SpecRestApi.Builder.create(this, "MySpecApi") .apiDefinition(apiDefinition) .build();
方法2:用CDK的Fn.sub处理CloudFormation动态变量
如果需要替换CloudFormation的动态值(比如资源ARN、栈输出),用Fn.sub实现:
- 修改
spec_file.yaml中的占位符为CloudFormation变量格式:
paths: /test: get: x-amazon-apigateway-integration: uri: "${MyLambdaArn}" # 其他配置项
- 在CDK代码中用
Fn.sub替换变量:
String specContent = Files.readString(Paths.get(specFilePath)); // 定义要替换的变量映射 Map<String, Object> variables = Map.of( "MyLambdaArn", myLambdaFunction.getFunctionArn() ); // 执行CloudFormation级别的变量替换 IResolvable resolvedSpec = Fn.sub(specContent, variables); InlineApiDefinition apiDefinition = ApiDefinition.fromInline(resolvedSpec); SpecRestApi specRestApi = SpecRestApi.Builder.create(this, "MySpecApi") .apiDefinition(apiDefinition) .build();
方法3:使用模板引擎处理复杂替换场景
如果有大量占位符或需要逻辑渲染,用Java模板引擎(如Mustache)处理:
- 添加Maven依赖:
<dependency> <groupId>com.github.spullara.mustache.java</groupId> <artifactId>compiler</artifactId> <version>0.9.10</version> </dependency>
- 修改
spec_file.yaml为Mustache模板格式:
paths: /test: get: summary: "API版本 {{apiVersion}}" x-amazon-apigateway-integration: uri: "{{lambdaArn}}"
- CDK代码中渲染模板:
// 初始化Mustache编译器 MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(new FileReader(specFilePath)); // 准备模板数据 Map<String, Object> templateData = new HashMap<>(); templateData.put("apiVersion", "v1"); templateData.put("lambdaArn", myLambdaFunction.getFunctionArn()); // 渲染得到最终spec内容 StringWriter writer = new StringWriter(); mustache.execute(writer, templateData).flush(); String renderedSpec = writer.toString(); // 创建ApiDefinition并实例化网关 InlineApiDefinition apiDefinition = ApiDefinition.fromInline(renderedSpec); SpecRestApi specRestApi = SpecRestApi.Builder.create(this, "MySpecApi") .apiDefinition(apiDefinition) .build();
注意:原代码中使用的
AWS::Include变换仅适用于静态文件引用,无法直接替换变量。如果需要变量替换,建议优先在本地处理内容后再传入CDK,或结合Fn.sub使用,避免依赖AWS::Include。
内容的提问来源于stack exchange,提问作者Ramón J Romero y Vigil
相关产品推荐
相关产品推荐

