首页 > 解决方案 > 如何使用 AWS CDK 将阶段变量传递给 api 网关中的 lambda 函数?

问题描述

我有一个 API 网关,它触发阶段变量指定的 lambda 函数stageVariables.lbfunc

在此处输入图像描述

如何使用 AWS CDK 创建这种集成请求?

看起来我应该handlerLambdaRestApi创建一个特殊的。

但我找不到任何执行此操作的示例代码。

以下是我当前的代码。我希望LambdaIntegration' 的处理程序可以由阶段变量确定。

# dev_lambda_function should be replaced by something else
dev_lambda_function = lambda_.Function(self, "MyServiceHandler",
            runtime=lambda_.Runtime.PYTHON_3_7,
            code=lambda_.Code.asset("resources"),
            handler="lambda_function.lambda_handler",
            description="My dev lambda function"
            )
stage_options = apigateway.StageOptions(stage_name="dev", 
    description="dev environment", 
    variables=dict(lbfunc="my-func-dev")
)
# What should I pass to the handler variable so that LambdaRestApi triggers the lambda function specified by the stage variable "stageVariables.lbfunc"?
api = apigateway.LambdaRestApi(self, "my-api",
            rest_api_name="My Service",
            description="My Service API Gateway",
            handler=dev_lambda_function,    
            deploy_options=stage_options)

标签: python-3.xamazon-web-servicesaws-api-gatewayaws-cdk

解决方案


最近刚刚解决了这个,我只是在这里记录一下我是如何解决的(在我忘记之前)

这里的想法是,当你的 API 方法被命中时,它会POST向你的lambda. 所以你为你的 lambda 创建一个“URL”,这样你的 API 方法就可以实现它。(好吧,我终于找到了,你可以看这里,对于这个链接中的第6项,看那里的URI)

  1. 创建一个Construct被调用的ApiIntegration

    class ApiIntegration(core.Construct):
    
       @property
       def integration(self):
         return self._integration
    
        def __init__(self, scope: core.Construct, id: str, function: _lambda,  ** kwargs):
         super().__init__(scope, id, **kwargs)
    
         # Here you construct a "URL" for your lambda
         api_uri = (
             f"arn:aws:apigateway:"
             f"{core.Aws.REGION}"
             f":lambda:path/2015-03-31/functions/"
             f"{function.function_arn}"
             f":"
             f"${{stageVariables.lambdaAlias}}" # this will appear in the picture u provide
             f"/invocations"
         )
         # Then here make a integration 
         self._integration = apigateway.Integration(
             type=apigateway.IntegrationType.AWS_PROXY,
             integration_http_method="POST",
             uri=api_uri
         )
    
  2. 在您的MyStack(core.Stack)课程中,您可以像这样使用它:

          # Here u define lambda, I not repeat again 
          my_lambda = ur lambda you define
    
          # define stage option 
          dev_stage_options = apigateway.StageOptions(
                                stage_name="dev",
                                    variables={
                                       "lambdaAlias": "dev" # define ur variable here
                                })
          # create an API, put in the stage options
          api = apigateway.LambdaRestApi(
                   self, "MyLittleNiceApi",
                   handler=my_lambda,
                   deploy_options=dev_stage_options
                )
    
          # Now use the ApiIntegration you create 
          my_integration = ApiIntegration(
              self, "MyApiIntegration", function=my_lambda)
    
         # make a method call haha
         my_haha_method = api.root.add_resource("haha")
    
         # put in the integration that define inside the Construct 
         my_haha_post_method = my_method.add_method('POST',
                               integration=my_integration.integration,
                               #...then whatever here)
    

现在您检查控制台,您的方法将具有 Lambda 函数stageVariable

现在你应该创建lambda alias,想法是这样的:

  • 你有 1 个 lambda
  • 为 lambda 制作 2 别名,dev然后prod
  • API stageVariable dev -> hit -> lambdadev别名
  • API stageVariable prod -> hit -> lambdaprod别名

每个 lambda 别名都会遇到不同版本的 lambda,例如:

  • dev别名命中$Latest
  • prod别名命中version:12

我在dev.to中讨论过这个

现在你有lambda:dev2lambda:prod个别名。为了让你method打不同的别名lambda:devlambda:prod你需要(The main idea)

Lambdadev/prod alias允许method点击。

创建版本、别名和权限的东西是完全不同的故事,所以这里没有提到。


推荐阅读