Lambda together with API Gateway
I use a stack where API Gateway invokes Lambda Function via aws_proxy and this works great. The docs of aws says Requests will be proxied to Lambda with request details available in the "context" of your handler function.
So I am wondering if I can invoke it the same way local with this plugin? I did a few tests and generally the invocation works good but didn't get it to run as I needed to.
e.g. apigateway gets a get request to path hello and this invokes the lambda function with a proxy and you get a corresponding answer (normal rest api).
Hi! So I believe you are asking for some request details to be set inside context?
If that is the case, I totally agree. But I would want to see the official specifications of when&what information is set into context.
As far as I have researched:
- the request details from API Gateway are set inside the
event, notcontexthttp://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html
With the Lambda proxy integration, API Gateway maps the entire client request to the input event parameter of the back-end Lambda function as follows:
- The official documentation of the
contextobject does not mention anything about request details from API Gateway http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
I'd appreciate it if you can show me where you found the documentation. Thanks!
To be honest I searched for a while now and it was not from the docs it was from tooltips in API Gateway:

So I think you already pointed to the correct URL to this Section: Input Format of a Lambda Function for Proxy Integration http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple-proxy-for-lambda-input-format
I tried it with an event based on above url but I get a 500 error with [Error: "value" required in setHeader("x-apigateway-context", value).]
What is stopping you from adding the full content of the API gateway request to your sample input data eg:
module.exports = {
resource: '/{proxy+}',
path: '/proxy',
httpMethod: 'POST',
headers: {
Accept: '*/*',
'Accept-Encoding': 'deflate, gzip',
'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',
Host: 'xxx.execute-api.ap-southeast-2.amazonaws.com',
Via: '1.1 xxx.cloudfront.net (CloudFront)',
'X-Amz-Cf-Id': 'xxx',
'X-Forwarded-For': '69.63.188.127, 54.239.134.6',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https',
'X-Hub-Signature': 'sha1=xxx'
},
queryStringParameters: null,
pathParameters: {
proxy: 'proxy'
},
stageVariables: null,
requestContext: {
accountId: 'xxx',
resourceId: '10999l',
stage: 'Prod',
requestId: '23dcdd78-eebf-11e6-97f8-25bc6590f380',
identity: {
cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
apiKey: null,
sourceIp: '69.63.188.127',
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: null,
user: null
},
resourcePath: '/{proxy+}',
httpMethod: 'POST',
apiId: 'jq8asr1y7f'
},
body: '{"object":"page","entry":[{"id":"xxx","time":1486641538051,"messaging":[{"sender":{"id":"xxx"},"recipient":{"id":"xxx"},"timestamp":1486596726994,"message":{"mid":"mid.1486596726994:606c1bfc42","seq":221055,"text":"test"}}]}]}',
isBase64Encoded: false
}
@mitchell-johnson As I mentioned, I tried with such an event but got a 500-Error and the comment: [Error: "value" required in setHeader("x-apigateway-context", value).]
@Mojo90 I just tested this myself, and it turns out that as the Document states, all the request information is stored in the event of the handler.
Therefore, as @mitchell-johnson states, you should be able to pass it into lambda-local as an input data.
You should also try and look at all of the event and context data, and you should be able to verify this yourself.
The text on the console (the screenshot you pasted) turns out to be wrong... A silly mistake on AWS's part.
http://willhamill.com/2016/12/12/aws-api-gateway-lambda-proxy-request-and-response-objects
[Error: "value" required in setHeader("x-apigateway-context", value).]
This sounds like a completely different issue. If you want help with this you should post your actual Lambda code.
I am currently using swagger-node with aws-serverless-express. To reproduce this error:
If you don't have used swagger before install it with:
$ npm install -g swagger
create swagger-node project (use express):
$ swagger project create hello-world
$ cd hello-world/
$ npm i --save aws-serverless-express
update app.js:
'use strict';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
module.exports = app; // for testing
var awsServerlessExpressMiddleware = require('aws-serverless-express/middleware');
app.use(awsServerlessExpressMiddleware.eventContext());
var config = {
appRoot: __dirname // required config
};
SwaggerExpress.create(config, function(err, swaggerExpress) {
if (err) { throw err; }
// install middleware
swaggerExpress.register(app);
var port = process.env.PORT || 10010;
app.listen(port);
if (swaggerExpress.runner.swagger.paths['/hello']) {
console.log('try this:\ncurl http://127.0.0.1:' + port + '/hello?name=Scott');
}
});
add lambda.js:
const awsServerlessExpress = require('aws-serverless-express');
const app = require('./app');
const server = awsServerlessExpress.createServer(app);
exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context);
add test-event.js:
module.exports = module.exports = {
resource: '/{proxy+}',
path: '/proxy',
httpMethod: 'POST',
headers: {
Accept: '*/*',
'Accept-Encoding': 'deflate, gzip',
'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',
Host: 'xxx.execute-api.ap-southeast-2.amazonaws.com',
Via: '1.1 xxx.cloudfront.net (CloudFront)',
'X-Amz-Cf-Id': 'xxx',
'X-Forwarded-For': '69.63.188.127, 54.239.134.6',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https',
'X-Hub-Signature': 'sha1=xxx'
},
queryStringParameters: null,
pathParameters: {
proxy: 'proxy'
},
stageVariables: null,
requestContext: {
accountId: 'xxx',
resourceId: '10999l',
stage: 'Prod',
requestId: '23dcdd78-eebf-11e6-97f8-25bc6590f380',
identity: {
cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
apiKey: null,
sourceIp: '69.63.188.127',
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: null,
user: null
},
resourcePath: '/{proxy+}',
httpMethod: 'POST',
apiId: 'jq8asr1y7f'
},
body: '{"object":"page","entry":[{"id":"xxx","time":1486641538051,"messaging":[{"sender":{"id":"xxx"},"recipient":{"id":"xxx"},"timestamp":1486596726994,"message":{"mid":"mid.1486596726994:606c1bfc42","seq":221055,"text":"test"}}]}]}',
isBase64Encoded: false
};
now run:
$ lambda-local -l lambda.js -e test-event.js
output:
info: Logs
info: ------
info: START RequestId: 7fe40093-8ca7-22f3-6c7f-b8ade54aac7d
EADDRINUSE /tmp/server0.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server1.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server2.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server3.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server4.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server5.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server6.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server7.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server8.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server9.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server10.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server11.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server12.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server13.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server14.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server15.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server16.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server17.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server18.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server19.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server20.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server21.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server22.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server23.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server24.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server25.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server26.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server27.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server28.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server29.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server30.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server31.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server32.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server33.sock incrementing socketPathSuffix.
EADDRINUSE /tmp/server34.sock incrementing socketPathSuffix.
[Error: `value` required in setHeader("x-apigateway-context", value).]
info: END
info: Message
info: ------
info: {
"statusCode": 500,
"body": "",
"headers": {}
}
info: -----
info: lambda-local successfully complete.
so does not work for me. At least a 404 should occur, as a 404 occurs when executing lambda function in aws console and no event data with proxy information is setted. Thx for your time!