APIGateway 代理资源未将路径参数获取到 Lambda

问题描述

我需要创建一个 API 端点,它将触发一个 Lambda 函数并从 S3 存储桶返回一个图像。

示例网址:https://abc.execute-api.eu-west-1.amazonaws.com/dev/xyz/00/01/23911414.jpeg

我使用 Web 控制台手动创建了一个 APIGateway 实例,并且运行良好。 我使用 CloudFormation 创建了相同的(我猜),但它不起作用。

Lambda 被触发,但它没有在 path 中获得 event 参数。

但我希望 Lambda 函数/xyz/00/01/23911414.jpeg 作为 event['path']

这是我的 CloudFormation 模板的一部分:

RestApi:
  Type: AWS::ApiGateway::RestApi
  Properties:
    Description: Example API Gateway
    EndpointConfiguration:
      Types:
        - REGIONAL
    Name: imaginary-api

ProxyResource:
  Type: AWS::ApiGateway::Resource
  Properties:
    RestApiId: !Ref RestApi
    ParentId: !GetAtt
      - RestApi
      - RootResourceId
    PathPart: '{proxy+}'

ProxyResourceANY:
  Type: AWS::ApiGateway::Method
  Properties:
    RestApiId: !Ref RestApi
    ResourceId: !Ref ProxyResource
    HttpMethod: ANY
    AuthorizationType: NONE
    MethodResponses:
      - StatusCode: 200
    Integration:
      Type: AWS
      IntegrationHttpMethod: POST
      Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImaginaryLambda.Arn}/invocations
      Credentials: !GetAtt ApiGatewayIamRole.Arn
      PassthroughBehavior: WHEN_NO_TEMPLATES
      RequestTemplates:
        "image/jpeg": ""
        "image/jpg": ""
      IntegrationResponses:
        - StatusCode: 200

RestAPIDeployment:
  Type: AWS::ApiGateway::Deployment
  DependsOn:
    - ProxyResource
  Properties:
    RestApiId: !Ref RestApi
    StageName: dev

ImaginaryInvoke:
  Type: AWS::Lambda::Permission
  Properties:
    Action: lambda:InvokeFunction
    FunctionName: !GetAtt ImaginaryLambda.Arn
    Principal: apigateway.amazonaws.com
    SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:abc/dev

这是我第一次使用 APIGateway,我可能在这里做错了什么。任何帮助将不胜感激。

更新

方法添加 RequestParameters 也不起作用。

RequestParameters:
  method.request.path.proxy: true

解决方法

您有different possible integrations

  • aws(需要数据映射)
  • aws_proxy
  • 模拟
  • http
  • http_proxy

AWS 集成类型需要数据映射才能获取所需的属性(选中 https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html)。

您可以使用 AWS_PROXY 获取包含路径属性的完整事件(检查:https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format)。

您可以返回二进制文件(注意内容长度)或返回 s3 预签名 url(例如通过重定向)。

,

让我回答我自己的问题。 我能够使用以下值解决此问题。

RestApi:
  Type: AWS::ApiGateway::RestApi
  Properties:
    Description: Example API Gateway
    BinaryMediaTypes:
      - "*/*"              # <-- Important
    EndpointConfiguration:
      Types:
        - REGIONAL
    Name: imaginary-api

  ProxyResourceANY:
    Type: AWS::ApiGateway::Method
    DependsOn:
      ProxyResource
    Properties:
      RestApiId: !Ref RestApi
      ResourceId: !Ref ProxyResource
      HttpMethod: ANY
      AuthorizationType: NONE
      RequestParameters:
        method.request.path.proxy: true  # <-- Important
      MethodResponses:
        - StatusCode: 200
      Integration:
        Type: AWS_PROXY  # <-- Important
        IntegrationHttpMethod: POST
        ContentHandling: CONVERT_TO_TEXT  # <-- Important,depends on your code
        PassthroughBehavior: WHEN_NO_MATCH
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImaginaryLambda.Arn}/invocations
        Credentials: !GetAtt ApiGatewayIamRole.Arn

我注意到的奇怪之处是,即使手动创建的在 Web 控制台中显示为 AWS,但当我将舞台导出为 Swagger 定义时,它显示为 AWS_PROXY。 比较两个 Swagger 定义对比较从 Export as Swagger + API Gateway Extensions 选项中取出的 YAML 很有帮助。