I have a CloudFormation template which sets up an API Gateway with a Lambda integration. When testing the integration via the AWS console it works.
When I attempt to use the HTTP method via Postman or Chrome, the response is null.
The full template can be seen here:
https://github.com/mattcanty/musicdown/blob/07b899d5924ab2fcc675cc521706b0c217e4e07e/cloudformation.yaml
I think something is not quite right here:
MusicdownsGet:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref ApiGateway
ResourceId: !Ref MusicdownResource
HttpMethod: GET
RequestParameters:
method.request.querystring.filter: true
AuthorizationType: NONE
RequestModels:
application/json: !Ref MusicdownModel
Integration:
Type: AWS
IntegrationHttpMethod: POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Lambda.Arn}/invocations
IntegrationResponses:
- StatusCode: 200
RequestTemplates:
application/json: "{ \"filter\": \"$input.params('filter')\" }"
MethodResponses:
- StatusCode: 200
Related
I'm trying to link an API Gateway to prefined lambda function. However it says unsupported property Uri. My lambda function is created in the given region as "SayHelloFunction".
SayHello:
Type: "AWS::ApiGateway::Method"
DependsOn:
- RootApi
- HelloResource
Properties:
RestApiId: !Ref RootApi
ResourceId: !Ref HelloResource
HttpMethod: PUT
MethodResponses:
- StatusCode: 200
AuthorizationType: NONE
ApiKeyRequired: true
Integration:
IntegrationHttpMethod: PUT
IntegrationResponses:
- StatusCode: 200
Type: AWS_PROXY
Uri: 'arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:xxxxxxxxxxxx:function:SayHelloFunctionFunctionArn/invocations'
Please help.
You can set using Lambda Arn attribute by calling like below shown.
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SayHelloFunction.Arn}/invocations
You will get more details here : https://github.com/aviboy2006/lambda-apigateway-sns-cnf-awsugblrdemo/blob/main/sample.yaml
I need to create an API endpoint, which will trigger a Lambda function and return an image from an S3 bucket.
Example URL: https://abc.execute-api.eu-west-1.amazonaws.com/dev/xyz/00/01/23911414.jpeg
I created an APIGateway instance manually using the web console and it’s working fine.
And I created the same (I guess) using CloudFormation and it’s not working.
The Lambda gets triggered, but it doesn't get the path parameter in the event.
But I want the Lambda function to get /xyz/00/01/23911414.jpeg as the event['path'].
Here is a part of my CloudFormation Template:
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
This is the first time I'm using APIGateway and I might have done something wrong here. Any help would be highly appreciated.
UPDATE:
Adding RequestParameters to the Method won't work either.
RequestParameters:
method.request.path.proxy: true
You have different possible integrations:
aws (requires data mapping)
aws_proxy
mock
http
http_proxy
The AWS integration type requires data mapping to get the required attributes (check https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html).
You can use AWS_PROXY to get the complete event (check: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format) including the path attribute.
You can return binary file (be careful with content length) or return a s3 presigned url (thru a redirection for example).
Let me answer my own question.
I was able to fix this with the following values.
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
Something strange I noticed is, even though the manually created one showed as AWS in the web console, it showed as AWS_PROXY when I exported the stage as a Swagger definition.
Comparing the two Swagger definitions helped me a lot comparing the YAMLs taken out from Export as Swagger + API Gateway Extensions option.
I'm following this tutorial and I can get it all working just fine using the console. I've converted the SQS queue and API creation to CloudFormation, but can't get the API method integration to work. I've used Former2 to convert the working method to CloudFormation (shown below) but I continue to get this error:
Invalid mapping expression specified: Validation Result:
warnings : [],
errors : [Invalid mapping expression specified: application/x-www-form-urlencoded]
(Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException;
Request ID: 1e40fc86-af05-4698-a91a-c1fa8930ee10; Proxy: null)
The CloudFormation template for my POST method is as follows:
ApiPostMsgMethod:
DependsOn: 'SqsQueue'
Type: AWS::ApiGateway::Method
Properties:
ApiKeyRequired: false
AuthorizationType: NONE
HttpMethod: POST
Integration:
Credentials: !GetAtt ApiSqsSendMsgRole.Arn
IntegrationHttpMethod: POST
IntegrationResponses:
- StatusCode: '200'
PassthroughBehavior: NEVER
RequestParameters:
integration.request.header.Content-Type: 'application/x-www-form-urlencoded'
RequestTemplates:
application/json : 'Action=SendMessage&MessageBody=$input.body'
TimeoutInMillis: 1200
Type: AWS
Uri: !Join
- ""
- - !Sub "arn:aws:apigateway:${AWS::Region}:sqs:path/${AWS::AccountId}/"
- !Sub ${EnvironmentName}-queue
MethodResponses:
- StatusCode: 200
OperationName: PostSqsItem
ResourceId: !Ref SqsResource
RestApiId: !Ref SqsRestApi
While Former2 returns the following template from a working POST method:
httpMethod: POST
authorizationType: NONE
apiKeyRequired: false
requestParameters: <empty object>
methodResponses:
200:
statusCode: 200
responseModels:
application/json: Empty
methodIntegration:
type: AWS
httpMethod: POST
uri: arn:aws:apigateway:###:sqs:path/###/###
credentials: arn:aws:iam::###:role/###
requestParameters:
integration.request.header.Content-Type: 'application/x-www-form-urlencoded'
requestTemplates:
application/json: Action=SendMessage&MessageBody=$input.body
passthroughBehavior: NEVER
timeoutInMillis: 29000
cacheNamespace: ###
integrationResponses:
200:
statusCode: 200
responseTemplates:
restApiId: ###
resourceId: ###
My references and substitutions appear to be working, but I still get this integration error. Am I missing something?
I think the trouble seems to me is coming from here
integration.request.header.Content-Type: 'application/x-www-form-urlencoded'
It should be something like
integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
I have a cloud-formation template to create API Gateway resource.
APIGateWayEQFAPIRequestGET:
DependsOn: LambdaEQFAPIPermission
Type: 'AWS::ApiGateway::Method'
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: AWS
IntegrationHttpMethod: POST
Uri: !Join
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/'
- !GetAtt
- LambdaEQFReportsAPIFunction
- Arn
- /invocations
IntegrationResponses:
- StatusCode: 200
ResponseTemplates:
application/json: $input.json('$.body')
RequestTemplates:
application/json: '{}'
ResourceId: !GetAtt
- APIGateWayEQFAPI
- RootResourceId
RestApiId: !Ref APIGateWayEQFAPI
MethodResponses:
- StatusCode: 200
Everything works as expected but "Use Lambda Proxy integration" is checked. I can manually uncheck it, but how do I uncheck using cloudformation.
I tried different Integration.Type: AWS/AWS_PROXY both did not have any impact on it.
I figured out why this is happening.
When I ran the stack I used AWS_PROXY. Then changing AWS_PROXY to AWS did not deploy the method. I had to rename the method and everything looks as expected.
I'm trying to create an API Gateway, which uses an AWS_IAM Authorizer, and using Amplify to sign in to my app using Federated Identities.
This all works fine, however I'm not getting an identity in my backend service.
What I want is to be able to access the identity of the user in my backend service. Eg a header with a user-id or something like that.
I've been looking at this example: https://github.com/matsev/cloudformation-api-gateway/blob/master/cloudformation.template to try to map the $context, however it seems it doesn't work with HTTP_PROXY?
RefreshProxy:
Type: AWS::ApiGateway::Resource
Properties:
ParentId:
Ref: SomeOtherHandler
PathPart: '{proxy+}'
RestApiId:
Ref: ApiGatewayRestApi
RefreshProxyMethod:
Type: AWS::ApiGateway::Method
Properties:
ResourceId:
Ref: RefreshProxy
RestApiId:
Ref: ApiGatewayRestApi
AuthorizationType: AWS_IAM
HttpMethod: POST
RequestParameters:
method.request.path.proxy: true
Integration:
IntegrationHttpMethod: POST
Type: HTTP_PROXY
Uri: url/{proxy}
IntegrationResponses:
- StatusCode: 200
RequestParameters:
integration.request.path.proxy: method.request.path.proxy
integration.request.header.Accept-Encoding: "'identity'"
PassthroughBehavior: WHEN_NO_MATCH
You need to add a header with the cognitoIdentityId from the context. So in the integration section you need:
integration.request.header.Identity: context.identity.cognitoIdentityId