我想使用AWS CDK定义API网关和APIG将代理的lambda。
OpenAPI规范支持Swagger规范的x-amazon-apigateway-integration
自定义扩展(详细信息here),为此需要lambda的调用URL。如果lambda与API在同一堆栈中定义,那么我在OpenAPI规范中看不到如何提供该lambda。我能想到的最好的办法是使用lambda定义一个堆栈,然后从中获取输出并运行sed
在OpenAPI规范中进行查找和替换以插入uri,然后创建第二个堆栈修改后的OpenAPI规范。
示例:
/items:
post:
x-amazon-apigateway-integration:
uri: "arn:aws:apigateway:eu-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-2:123456789012:function:MyStack-SingletonLambda4677ac3018fa48679f6-B1OYQ50UIVWJ/invocations"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
type: "aws_proxy"
Q1。这似乎是一个鸡与蛋的问题,以上是实现此目的的唯一方法吗?
我试图使用defaultIntegration
CDK构造的defaultIntegration
属性。该文档指出:
集成,默认使用此集成创建的所有方法 API,除非指定了集成。
这似乎应该能够使用CDK规范中定义的lambda定义默认积分,因此,所有方法都可以使用此积分,而无需事先知道lambda的uri。
因此,我尝试了此:
SpecRestApi
SingletonFunction myLambda = ...
SpecRestApi openapiRestApi = SpecRestApi.Builder.create(this, "MyApi")
.restApiName("MyApi")
.apiDefinition(ApiDefinition.fromAsset("openapi.yaml"))
.defaultIntegration(LambdaIntegration.Builder.create(myLambda)
.proxy(false)
.build())
.deploy(true)
.build();
中定义的OpenAPI规范不包含openapi.yaml
节;它只有一个在标准OpenApi 3规范中定义的GET方法。
但是,当我尝试部署它时,出现错误:
x-amazon-apigateway-integration
这似乎是一个错误,所以我提了一个No integration defined for method (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 56113150-1460-4ed2-93b9-a12618864582)
。
Q2。如何使用CDK定义API网关和Lambda,并通过OpenAPI规范将两者连接在一起?
here跟踪我的追踪情况。同时,我对该问题this CDK issue的评论进行了指导,并提出了一种解决方法。
[我使用here来解析我的OpenAPI规范文件并替换其中引用API网关的调用ARN(其本身引用Lambda ARN)的模板值。
https://github.com/spullara/mustache.java
请注意,Map<String, Object> variables = new HashMap<>();
variables.put("restapi-lambda", String.format("arn:aws:apigateway:%s:lambda:path/2015-03-31/functions/%s/invocations", props.getEnv().getRegion(), myLambda.getFunctionArn()));
Writer writer = new StringWriter();
MustacheFactory mf = new DefaultMustacheFactory();
Object openapiSpecAsObject;
try (Reader reader = new FileReader(new File("myapi.yaml"))) {
Mustache mustache = mf.compile(reader, "OAS");
mustache.execute(writer, scopes);
writer.flush();
ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
openapiSpecAsObject = yamlMapper.readValue(writer.toString(), Object.class);
}
SpecRestApi openapiRestApi = SpecRestApi.Builder.create(this, "MyRestApi")
.restApiName("MyRestApi")
.apiDefinition(ApiDefinition.fromInline(openapiSpecAsObject))
.deploy(true)
.build();
是引用props
道具的变量,Stack
是引用myLambda
的变量。]>
我的OpenAPI规范如下(已删除标题和模型部分:]:>
SingletonFunction
还请注意,当我授予API网关这样的权限来调用lambda时:
paths: /items: get: summary: List all items. responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/ItemList' x-amazon-apigateway-integration: uri: "{{restapi-lambda}}" passthroughBehavior: "when_no_match" httpMethod: "POST" type: "aws_proxy"
我仍然收到500错误,并且在日志中,我看到“ Lambda函数的无效权限”错误消息。如果我向Lambda添加权限,如下所示:
myLambda.grantInvoke(ServicePrincipal.Builder.create("apigateway.amazonaws.com") .build());
然后,我目前需要重新部署API,以使权限生效。我仍在研究如何避免这种情况。