AWS CDK如何根据OpenApi规范创建由Lambda支持的API网关?

问题描述 投票:1回答:1

我想使用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规范将两者连接在一起?

amazon-web-services aws-lambda swagger aws-api-gateway openapi
1个回答
0
投票

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,以使权限生效。我仍在研究如何避免这种情况。

© www.soinside.com 2019 - 2024. All rights reserved.