问题描述
我需要创建一个 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 很有帮助。