Micronaut unable to process AWS Http API gateway V2 calling Lambda - amazon-web-services

{
"version": "2.0",
"routeKey": "ANY /petclinic",
"rawPath": "/dev/petclinic",
"rawQueryString": "",
"headers": {
"accept": "*/*",
"authorization": "Bearer eyJhbGciOiJSUzI1NiI.....vdW5nIExlZSIsImNfaWQiOiI3RTZuYUY1UFEzbUE0NEtITV95bzh3IiwidV9pZC.......",
"content-length": "0",
"host": "sss.execute-api.us-west-2.amazonaws.com",
"user-agent": "curl/7.73.0",
"x-amzn-trace-id": "Root=1-5s069-ss",
"x-forwarded-for": "23.240.195.204",
"x-forwarded-port": "443",
"x-forwarded-proto": "https"
},
"requestContext": {
"accountId": "1234567890",
"apiId": "dsdsd",
"authorizer": {
"jwt": {
"claims": {
"aud": "petclinic-dev",
"auth_time": "1606511194",
"c_id": "7E6ssssM_ysw",
"c_type": "doctor",
"email": "user#petclinic.com",
"email_verified": "true",
"exp": "1606514794",
"firebase": "map[identities:map[email:[user#petclinic.com]] sign_in_provider:password]",
"iat": "1606511194",
"iss": "https://securetoken.google.com/petclinic-dev",
"name": "ss-dd, test",
"sub": "3fzw9dddBkibf2",
"u_id": "SPfrddULDQ",
"user_id": "3fzddddnbk0dddf2"
},
"scopes": null
}
},
"domainName": "abcdef.execute-api.us-west-2.amazonaws.com",
"domainPrefix": "abcdef",
"http": {
"method": "GET",
"path": "/dev/petclinic",
"protocol": "HTTP/1.1",
"sourceIp": "23.240.195.204",
"userAgent": "curl/7.73.0"
},
"requestId": "Wrdddj_vvHcESOQ=",
"routeKey": "ANY /petclinic",
"stage": "dev",
"time": "27/Nov/2020:21:32:26 +0000",
"timeEpoch": 1606512746004
},
"stageVariables": {
"StageVar": "Value"
},
"isBase64Encoded": false
}
val context : Context = mock()
val handler = MicronautLambdaContainerHandler()
val output = ByteArrayOutputStream()
// inputJson is the above string AWS Http API v2
handler.proxyStream(inputJson.toString().byteInputStream(), output, context)
I am getting the bellow error. Is Micronaut unable to parse latest AWS Http Api proxy call to lambda?
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.String out of START_OBJECT token
at [Source: (ByteArrayInputStream); line: 21, column: 14] (through reference chain: com.amazonaws.serverless.proxy.model.AwsProxyRequest["requestContext"]->com.amazonaws.serverless.proxy.model.AwsProxyRequestContext["authorizer"]->com.amazonaws.serverless.proxy.model.ApiGatewayAuthorizerContext["jwt"])

Related

Taxonomy of event- driven Lambda messages?

I'm building event driven AWS stacks with Lambda+APIGateway+SQS+SNS+S3+DynamoDB.
One of my constant frustrations is that, if you bind any of the above to Lambda (either through event notifications or event source mappings), the formats of the event messages received by the Lambda are completely different - so a message sent by S3 is completely different to one sent by SQS which is completely different to one sent by DynamoDB etc.
Normally I have to set up a Cloudformation stack with an event source + event source mapping + Lambda, then push a message onto the event source to see what message actually results. What a giant pain.
Is there not a single combined resource out there which lists the different schema formats of different event messages ? Hoping someone can point me in the right direction.
Lambda console provides some example events in Configure test event. Here are the examples from the console for the services you mentioned.
APIGateway (aws proxy)
{
"body": "eyJ0ZXN0IjoiYm9keSJ9",
"resource": "/{proxy+}",
"path": "/path/to/resource",
"httpMethod": "POST",
"isBase64Encoded": true,
"queryStringParameters": {
"foo": "bar"
},
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"pathParameters": {
"proxy": "/path/to/resource"
},
"stageVariables": {
"baz": "qux"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "1234567890.execute-api.us-east-1.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Custom User Agent String",
"Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
"X-Forwarded-For": "127.0.0.1, 127.0.0.2",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Cache-Control": [
"max-age=0"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"0123456789.execute-api.us-east-1.amazonaws.com"
],
"Upgrade-Insecure-Requests": [
"1"
],
"User-Agent": [
"Custom User Agent String"
],
"Via": [
"1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
],
"X-Forwarded-For": [
"127.0.0.1, 127.0.0.2"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"accessKey": null,
"sourceIp": "127.0.0.1",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Custom User Agent String",
"user": null
},
"path": "/prod/path/to/resource",
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}
SQS
{
"Records": [
{
"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
"receiptHandle": "MessageReceiptHandle",
"body": "Hello from SQS!",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1523232000000",
"SenderId": "123456789012",
"ApproximateFirstReceiveTimestamp": "1523232000001"
},
"messageAttributes": {},
"md5OfBody": "7b270e59b47ff90a553787216d55d91d",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
"awsRegion": "us-east-1"
}
]
}
SNS
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:us-east-1:{{{accountId}}}:ExampleTopic",
"Sns": {
"Type": "Notification",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"TopicArn": "arn:aws:sns:us-east-1:123456789012:ExampleTopic",
"Subject": "example subject",
"Message": "example message",
"Timestamp": "1970-01-01T00:00:00.000Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"UnsubscribeUrl": "EXAMPLE",
"MessageAttributes": {
"Test": {
"Type": "String",
"Value": "TestString"
},
"TestBinary": {
"Type": "Binary",
"Value": "TestBinary"
}
}
}
}
]
}
S3 (put)
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "1970-01-01T00:00:00.000Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "EXAMPLE"
},
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"responseElements": {
"x-amz-request-id": "EXAMPLE123456789",
"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "testConfigRule",
"bucket": {
"name": "example-bucket",
"ownerIdentity": {
"principalId": "EXAMPLE"
},
"arn": "arn:aws:s3:::example-bucket"
},
"object": {
"key": "test/key",
"size": 1024,
"eTag": "0123456789abcdef0123456789abcdef",
"sequencer": "0A1B2C3D4E5F678901"
}
}
}
]
}
DynamoDB
{
"Records": [
{
"eventID": "c4ca4238a0b923820dcc509a6f75849b",
"eventName": "INSERT",
"eventVersion": "1.1",
"eventSource": "aws:dynamodb",
"awsRegion": "us-east-1",
"dynamodb": {
"Keys": {
"Id": {
"N": "101"
}
},
"NewImage": {
"Message": {
"S": "New item!"
},
"Id": {
"N": "101"
}
},
"ApproximateCreationDateTime": 1428537600,
"SequenceNumber": "4421584500000000017450439091",
"SizeBytes": 26,
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899"
},
{
"eventID": "c81e728d9d4c2f636f067f89cc14862c",
"eventName": "MODIFY",
"eventVersion": "1.1",
"eventSource": "aws:dynamodb",
"awsRegion": "us-east-1",
"dynamodb": {
"Keys": {
"Id": {
"N": "101"
}
},
"NewImage": {
"Message": {
"S": "This item has changed"
},
"Id": {
"N": "101"
}
},
"OldImage": {
"Message": {
"S": "New item!"
},
"Id": {
"N": "101"
}
},
"ApproximateCreationDateTime": 1428537600,
"SequenceNumber": "4421584500000000017450439092",
"SizeBytes": 59,
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899"
},
{
"eventID": "eccbc87e4b5ce2fe28308fd9f2a7baf3",
"eventName": "REMOVE",
"eventVersion": "1.1",
"eventSource": "aws:dynamodb",
"awsRegion": "us-east-1",
"dynamodb": {
"Keys": {
"Id": {
"N": "101"
}
},
"OldImage": {
"Message": {
"S": "This item has changed"
},
"Id": {
"N": "101"
}
},
"ApproximateCreationDateTime": 1428537600,
"SequenceNumber": "4421584500000000017450439093",
"SizeBytes": 38,
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899"
}
]
}

How to test a GET and POST call from inside of Lambda

I am learning Lambda, have created a Cloud Watch Metrics which triggers Lambda every one minute. At present, my Lambda function is executing properly. But I want to make a fake GET and POST call from inside of Lambda. Something like below:
var https = require('https');
exports.handler = (event, context, callback) => {
var params = {
host: "example.com",
path: "/api/v1/yourmethod"
};
var req = https.request(params, function(res) {
let data = '';
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
console.log("DONE");
console.log(JSON.parse(data));
});
});
req.end();
};
Question - Since I don't have any GET and POST endpoint/Code hosted in AWS is there any way I can test whether my GET call and POST call from inside of Lambda is working fine? Is there any way in AWS to put together a fake endpoint or something in AWS and make REST call to it for testing purposes?
You can use JSONPlaceholder's APIs for testing calls to external APIs,
They have released Fake Online REST APIs for Testing and Prototyping
You can test calling different http method calls like GET, PUT, POST, DELETE
https://jsonplaceholder.typicode.com/
In case you are using Lambda proxy integration Event will contents a lot of additional information about request: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
{
"message": "Hello me!",
"input": {
"resource": "/{proxy+}",
"path": "/hello/world",
"httpMethod": "POST",
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"cache-control": "no-cache",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Content-Type": "application/json",
"headerName": "headerValue",
"Host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
"Postman-Token": "9f583ef0-ed83-4a38-aef3-eb9ce3f7a57f",
"User-Agent": "PostmanRuntime/2.4.5",
"Via": "1.1 d98420743a69852491bbdea73f7680bd.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "pn-PWIJc6thYnZm5P0NMgOUglL1DYtl0gdeJky8tqsg8iS_sgsKD1A==",
"X-Forwarded-For": "54.240.196.186, 54.182.214.83",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders":{
'Accept':[
"*/*"
],
'Accept-Encoding':[
"gzip, deflate"
],
'cache-control':[
"no-cache"
],
'CloudFront-Forwarded-Proto':[
"https"
],
'CloudFront-Is-Desktop-Viewer':[
"true"
],
'CloudFront-Is-Mobile-Viewer':[
"false"
],
'CloudFront-Is-SmartTV-Viewer':[
"false"
],
'CloudFront-Is-Tablet-Viewer':[
"false"
],
'CloudFront-Viewer-Country':[
"US"
],
'':[
""
],
'Content-Type':[
"application/json"
],
'headerName':[
"headerValue"
],
'Host':[
"gy415nuibc.execute-api.us-east-1.amazonaws.com"
],
'Postman-Token':[
"9f583ef0-ed83-4a38-aef3-eb9ce3f7a57f"
],
'User-Agent':[
"PostmanRuntime/2.4.5"
],
'Via':[
"1.1 d98420743a69852491bbdea73f7680bd.cloudfront.net (CloudFront)"
],
'X-Amz-Cf-Id':[
"pn-PWIJc6thYnZm5P0NMgOUglL1DYtl0gdeJky8tqsg8iS_sgsKD1A=="
],
'X-Forwarded-For':[
"54.240.196.186, 54.182.214.83"
],
'X-Forwarded-Port':[
"443"
],
'X-Forwarded-Proto':[
"https"
]
},
"queryStringParameters": {
"name": "me",
"multivalueName": "me"
},
"multiValueQueryStringParameters":{
"name":[
"me"
],
"multivalueName":[
"you",
"me"
]
},
"pathParameters": {
"proxy": "hello/world"
},
"stageVariables": {
"stageVariableName": "stageVariableValue"
},
"requestContext": {
"accountId": "12345678912",
"resourceId": "roq9wj",
"stage": "testStage",
"requestId": "deef4878-7910-11e6-8f14-25afc3e9ae33",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "192.168.196.186",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "PostmanRuntime/2.4.5",
"user": null
},
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "gy415nuibc"
},
"body": "{\r\n\t\"a\": 1\r\n}",
"isBase64Encoded": false
}
}

How to enable CORS configuration in WSO2 for a specific API by using REST API?

I am creating and publishing APIs using WSO2 REST APIs and not from its UI because i have hundreds of WSO2 APIs to manage. I use swagger file(in json format) to configure all the details about my API and then publish this swagger file using curl command. I want to enable CORS configuration for my WSO2 APIs.
The documentation provided for WSO2 APIs provides information only about enabling CORS config via UI. Here is the link.
I could not find any info as to how i can enable it by any means other than directly from its UI. I have tried adding the following field in the API's swagger file but this change is not reflected in the published API.
"CORSConfiguration": {
"Enabled": "true",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,PATCH,OPTIONS",
"Access-Control-Allow-Headers": "authorization,Access-Control-Allow-Origin,Content-Type,SOAPAction",
"Access-Control-Allow-Credentials": "false"
}
Any help to enable the CORS configuration for a particular API will be appreciated. Thanks :)
CORS information should go in the API create/update payload like this.
"corsConfiguration": {
"accessControlAllowOrigins": ["*"],
"accessControlAllowHeaders": [
"authorization",
"Access-Control-Allow-Origin",
"Content-Type",
"SOAPAction"
],
"accessControlAllowMethods": [
"GET",
"PUT",
"POST",
"DELETE",
"PATCH",
"OPTIONS"
],
"accessControlAllowCredentials": false,
"corsConfigurationEnabled": false
}
See the sample payload in [1].
[1] https://docs.wso2.com/display/AM260/apidocs/publisher/#!/operations#APIIndividual#apisPost
#Bee, here is what i tried to do.
{
"swagger": "2.0",
"info": {
"description": "Registration Type Master",
"version": "1.0",
"title": "Test_Entity_Master_API",
"termsOfService": "urn:tos",
"contact": {"name":"RD"},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0"
}
},
"host": "http://sampleurl.com/",
"basePath": "/samplemethod",
"schemes": [
"http"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/regtype/createregtype": {
"post": {
"summary": "Create reg type entry",
"tags": [
"Registration Type Master"
],
"deprecated": false,
"produces": [
"application/json"
],
"parameters": [
{
"name": "Body",
"in": "body",
"required": true,
"description": "",
"schema": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
}
],
"responses": {
"200": {
"description": "",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"error": {
"type": "boolean",
"default": false
},
"message": {
"type": "string"
},
"data": {
"type": "object"
}
}
}
},
"500": {
"description": "",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"default": false
},
"error": {
"type": "boolean"
},
"message": {
"type": "string"
},
"data": {
"type": "object"
}
}
}
}
}
}
}
},
"tags": [
{
"name": "entity-master-controller",
"description": "Entity Master Controller"
}
],
"corsConfiguration": {
"accessControlAllowOrigins": ["https://dtdevsso.ril.com"],
"accessControlAllowHeaders":[
"authorization",
"Access-Control-Allow-Origin",
"Content-Type",
"SOAPAction"
],
"accessControlAllowMethods":[
"GET",
"PUT",
"POST",
"DELETE",
"PATCH",
"OPTIONS"
],
"accessControlAllowCredentials": "true",
"corsConfigurationEnabled": "true"
}
}
In this swagger file, inspite of adding the CORS payload, it is not reflected after publishing the API through the swagger file.
To setup CORS support you must first define an OPTIONS method in your resource that returns the required headers.
All paths in swagger need a cors option chunk. this is the chunk.
"/users":
{
"options": {
"summary": "CORS support",
"description": "Enable CORS by returning correct headers\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"CORS"
],
"x-amazon-apigateway-integration": {
"type": "mock",
"requestTemplates": {
"application/json": "{\n \"statusCode\" : 200\n}\n"
},
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"responseTemplates": {
"application/json": "{}\n"
}
}
}
},
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
}
}
}
For more details you can visit this link
I used the following payload for creating/updating an API in WSO2.
It is working perfectly. Sorry for the delayed update on this.
{
"name": "%apiName%",
"description": "%apiDescription%",
"context": "/%apiName%",
"version": "%apiVersion%",
"provider": "%apiProvider%",
"apiDefinition": "%swaggger_extended.json% // Input swagger file",
"wsdlUri": null,
"status": "CREATED",
"responseCaching": "Disabled",
"cacheTimeout": 300,
"destinationStatsEnabled": false,
"isDefaultVersion": false,
"type": "HTTP",
"transport": [
"http",
"https"
],
"tags": ["%apiTags%"],
"tiers": ["%apiTiersCollection%"],
"visibility": "%apiVisibility%",
"visibleRoles": [],
"endpointConfig": "%endPointConfig%",
"gatewayEnvironments": "Production and Sandbox",
"subscriptionAvailability": null,
"subscriptionAvailableTenants": [],
"businessInformation": {
"businessOwnerEmail": "%BizOwnerName#ril.com%",
"technicalOwnerEmail": "%TechOwnerName#ril.com%",
"technicalOwner": "%TechOwnerName%",
"businessOwner": "%BizOwnerName%"
},
"corsConfiguration": {
"accessControlAllowOrigins": ["originURL"],
"accessControlAllowHeaders": [
"authorization",
"Access-Control-Allow-Origin",
"Content-Type",
"SOAPAction"
],
"accessControlAllowMethods": [
"GET",
"PUT",
"POST",
"DELETE",
"PATCH",
"OPTIONS"
],
"accessControlAllowCredentials": false,
"corsConfigurationEnabled": true
}
}

API Gateway seems to corrupt or truncate base64 encoded binary data

I am using AWS API Gateway to consume an image file to send to a Lambda function. The POST reaches my Lambda function just fine, with the binary data transformed into a base64 string, but when I try to decode that base64 string and save it as an image, the image cannot be decoded. In fact, the string returned after transformation is smaller than the image itself, which makes me think that something is going wrong. I have tried simply returning the string provided to the Lambda function as the response and decoding that locally, which doesn't work either.
Here is the configuration for my API Gateway method:
"/photo/{photo_id}": {
"x-amazon-apigateway-any-method": {
"consumes": [
"image/jpeg",
"image/jpg"
],
"produces": [
"application/json",
"image/jpg"
],
"parameters": [
{
"name": "Content-Type",
"in": "header",
"required": false,
"type": "string"
},
{
"name": "Accept",
"in": "header",
"required": false,
"type": "string"
},
{
"name": "photo_id",
"in": "path",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "Empty",
"required": true,
"schema": {
"$ref": "#/definitions/Empty"
}
},
{
"in": "body",
"name": "Empty",
"required": true,
"schema": {
"$ref": "#/definitions/Empty"
}
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
},
"500": {
"description": "500 response"
}
},
"x-amazon-apigateway-integration": {
"credentials": "redacted",
"uri": "redacted",
"responses": {
"default": {
"statusCode": "200"
},
".*Error.*": {
"statusCode": "500"
}
},
"requestParameters": {
"integration.request.header.Accept": "method.request.header.Accept",
"integration.request.header.Content-Type": "method.request.header.Content-Type"
},
"requestTemplates": {
"image/jpeg": "{\"photo\": \"$input.body\", \"photo_id\": \"$input.params('photo_id')\", \"app_id\": \"$input.params('x-app-id')\", \"httpMethod\": \"$context.httpMethod\"}",
"image/jpg": "{\"photo\": \"$input.body\", \"photo_id\": \"$input.params('photo_id')\", \"app_id\": \"$input.params('x-app-id')\", \"httpMethod\": \"$context.httpMethod\"}"
},
"passthroughBehavior": "when_no_templates",
"httpMethod": "POST",
"contentHandling": "CONVERT_TO_TEXT",
"type": "aws"
}
}
}
And the simple Lambda function to return the string back:
def lambda_handler(event, context):
photo_string = event['photo']
return photo_string
The cURL command I'm using to test the implementation:
curl -X POST https://execute-api.eu-central-1.amazonaws.com/prod/photo/new -H "Content-Type: image/jpg" -H "x-app-id:test" -d #IMG_1642.jpg
Any idea why the base64 that is returned would be different?
I figured it out, I needed to be using --data-binary in my cURL invocation instead of just -d which is an alias for --data-ascii. It works fine now.

Unable to execute Lambda in Async mode via API Gateway POST request

Why currently there no way to execute AWS Lambda in asynchronous mode via Gateway API without involving intermediary Lambda just for calling invoke() method?
Even if i add integration like this:
r = client.put_integration(
restApiId=rest_api_id,
resourceId=resource_id,
httpMethod='POST',
type='AWS',
integrationHttpMethod='POST',
uri=uri,
requestParameters={
'integration.request.header.X-Amz-Invocation-Type': "'Event'",
'integration.request.header.Invocation-Type': "'Event'"
}
)
It still executed synchronously...
Are there some platform limitation or so?
I have an example Swagger document which you can switch invocation type to Lambda function. I guess you already got how to map the header to trigger the different invocation types, but I think you might forget to deploy the API.
Swagger
{
"swagger": "2.0",
"info": {
"version": "2016-02-11T22:00:31Z",
"title": "LambdaAsync"
},
"host": "<placeholder>",
"basePath": "<placeholder>",
"schemes": [
"https"
],
"paths": {
"/": {
"get": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "X-Amz-Invocation-Type",
"in": "header",
"required": false,
"type": "string"
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"x-amazon-apigateway-integration": {
"passthroughBehavior": "when_no_match",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:<account>:function:<function_name>/invocations?Qualifier=$LATEST",
"responses": {
"default": {
"statusCode": "200"
}
},
"requestParameters": {
"integration.request.header.X-Amz-Invocation-Type": "method.request.header.X-Amz-Invocation-Type"
},
"type": "aws"
}
}
}
},
"definitions": {
"Empty": {
"type": "object",
"title": "Empty Schema"
}
}
}