如何使用 NodeJS 在本地测试 AWS Lambda 处理程序?
Posted
技术标签:
【中文标题】如何使用 NodeJS 在本地测试 AWS Lambda 处理程序?【英文标题】:How to test AWS Lambda handler locally using NodeJS? 【发布时间】:2019-01-31 19:05:07 【问题描述】:我正在按照these 的说明创建一个在 Lambda 中执行的基本网络爬虫。我有编写 selenium 代码的经验,但没有使用 Node JS。我让项目在 Lambda 中运行,但是当我尝试在本地编辑项目以执行我想要的 selenium 代码时,它不起作用。当我运行node index.js
时,exports.handler
中的任何内容都不会被执行。我将如何在本地执行这个项目?谢谢!
【问题讨论】:
您需要致电您的function
,而不仅仅是导出声明。导入您导出的handler.js
分配给index.js
中的变量并调用您的函数。 (假设exports.handler
是function
。)
【参考方案1】:
这就是我所做的:
index.js
exports.handler = async (event) =>
console.log('hello world');
const response =
statusCode: 200,
body: JSON.stringify('Hello from Lambda!')
;
return response;
;
package.json
"scripts":
"locally": "node -e \"console.log(require('./index').handler(require('./event.json')));\""
event.json
"Records": [
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "eu-central-1",
"eventTime": "1970-01-01T00:00:00.000Z",
"eventName": "ObjectCreated:Put",
"userIdentity":
"principalId": "AIDAJDPLRKLG7UEXAMPLE"
,
"requestParameters":
"sourceIPAddress": "127.0.0.1"
,
"responseElements":
"x-amz-request-id": "C3D13FE58DE4C810",
"x-amz-id-2": "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
,
"s3":
"s3SchemaVersion": "1.0",
"configurationId": "testConfigRule",
"bucket":
"name": "my-bucket",
"ownerIdentity":
"principalId": "A3NL1KOZZKExample"
,
"arn": "arn:aws:s3:::my-bucket"
,
"object":
"key": "HelloWorld.jpg",
"size": 1024,
"eTag": "d41d8cd98f00b204e9800998ecf8427e",
"versionId": "096fKKXTRTtl3on89fVO.nfljtsv6qko"
]
壳牌
npm run locally
输出
> node -e "console.log(require('./index').handler());"
hello world
Promise statusCode: 200, body: '"Hello from Lambda!"'
【讨论】:
为什么需要额外的npm
步骤?只运行 node 命令更直接,对吧?
不需要额外的 npm 步骤。这对我来说只是一种方便,因为我可以在调用中添加特定于该代码库的参数。坦率地说,我更容易记住:)
在这种情况下我们如何传递事件?
我喜欢方便。但是,如果您想针对您的 lambda 函数运行 10 个不同的测试场景怎么办?你如何传递不同的事件变体——快乐路径、悲伤路径、空事件、无效数据等?
您可以创建一个名为 sad-event.json 的新 json 文件,并需要该文件而不是“./event.json”。您可以将它们组织在一个名为 test-events 的文件夹中,因此您的路径可以是“test-events/happy.json”【参考方案2】:
您需要从另一个文件调用您的处理程序函数,比如说testHandler.js
,以便通过 NodeJs 运行。
这将像这样完成
//import your handler file or main file of Lambda
let handler = require('./handler');
//Call your exports function with required params
//In AWS lambda these are event, content, and callback
//event and content are JSON object and callback is a function
//In my example i'm using empty JSON
handler.handlerEvent( , //event
, //content
function(data,ss) //callback function with two arguments
console.log(data);
);
现在您可以使用node testHandler.js
来测试您的处理函数。
编辑:示例事件和内容数据按要求
事件:
"resource": "/API/PATH",
"path": "/API/PATH",
"httpMethod": "POST",
"headers":
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8",
"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": "IN",
"content-type": "application/json",
"Host": "url.us-east-1.amazonaws.com",
"origin": "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
"Via": "2.0 XXXXXXXXXXXXXX.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "XXXXXXXXXX51YYoOl75RKjAWEhCyna-fuQqEBjSL96TMkFX4H0xaZQ==",
"X-Amzn-Trace-Id": "Root=1-XXX03c23-25XXXXXX948c8fba065caab5",
"x-api-key": "SECUREKEY",
"X-Forwarded-For": "XX.XX.XXX.XXX, XX.XXX.XX.XXX",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
,
"multiValueHeaders":
"Accept": [ "*/*" ],
"Accept-Encoding": [ "gzip, deflate, br" ],
"Accept-Language": [ "en-GB,en-US;q=0.9,en;q=0.8" ],
"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": [ "IN" ],
"content-type": [ "application/json" ],
"Host": [ "apiurl.us-east-1.amazonaws.com" ],
"origin": [ "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop" ],
"User-Agent": [ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36" ],
"Via": [ "2.0 XXXXXXXXXXXXXX.cloudfront.net (CloudFront)" ],
"X-Amz-Cf-Id": [ "XXXXXXXXXhCyna-fuQqEBjSL96TMkFX4H0xaZQ==" ],
"X-Amzn-Trace-Id": [ "Root=1-XXXXXXX67339948c8fba065caab5" ],
"x-api-key": [ "SECUREAPIKEYPROVIDEDBYAWS" ],
"X-Forwarded-For": [ "xx.xx.xx.xxx, xx.xxx.xx.xxx" ],
"X-Forwarded-Port": [ "443" ],
"X-Forwarded-Proto": [ "https" ]
,
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext":
"resourceId": "xxxxx",
"resourcePath": "/api/endpoint",
"httpMethod": "POST",
"extendedRequestId": "xxXXxxXXw=",
"requestTime": "29/Nov/2018:19:21:07 +0000",
"path": "/env/api/endpoint",
"accountId": "XXXXXX",
"protocol": "HTTP/1.1",
"stage": "env",
"domainPrefix": "xxxxx",
"requestTimeEpoch": 1543519267874,
"requestId": "xxxxxxx-XXXX-xxxx-86a8-xxxxxa",
"identity":
"cognitoIdentityPoolId": null,
"cognitoIdentityId": null,
"apiKey": "SECUREAPIKEYPROVIDEDBYAWS",
"cognitoAuthenticationType": null,
"userArn": null,
"apiKeyId": "xxXXXXxxxxxx",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
"accountId": null,
"caller": null,
"sourceIp": "xx.xxx.xxx.xxx",
"accessKey": null,
"cognitoAuthenticationProvider": null,
"user": null
,
"domainName": "url.us-east-1.amazonaws.com",
"apiId": "xxxxx"
,
"body": "\n \"city\": \"Test 1 City\",\n \"state\": \"NY\",\n \"zipCode\": \"11549\"\n",
"isBase64Encoded": false
内容:
"callbackWaitsForEmptyEventLoop": true,
"logGroupName": "/aws/lambda/lambda-name",
"logStreamName": "2018/11/29/[$LATEST]xxxxxxxxxxxb",
"functionName": "lambda-name",
"memoryLimitInMB": "1024",
"functionVersion": "$LATEST",
"invokeid": "xxxxx-xxx-11e8-xxx-xxxxxxxf9",
"awsRequestId": "xxxxxx-xxxxx-11e8-xxxx-xxxxxxxxx",
"invokedFunctionArn": "arn:aws:lambda:us-east-1:xxxxxxxx:function:lambda-name"
【讨论】:
您能否举例说明在 AWS Lambda 上调用event
时通常的样子?
@PetrusTheron 添加了示例事件和内容。
事件看起来不同,具体取决于事件的触发器。在编辑 lambda 的 Web UI 中,测试事件选择下拉列表将“配置测试事件”作为选项之一。在那里,他们为所有类型的触发器提供原型事件。【参考方案3】:
在您的index.js
中,刚刚定义并导出了一个处理函数,但没有人调用它。在 Lambda 环境中,一些 AWS 代码将使用消息调用此处理程序。在您的本地环境中,您必须自己调用您的处理程序。
你也可以看看this doc,这是一种在本地环境中“模拟”Lambda的方法。
【讨论】:
【参考方案4】:您可以查看lambda-local。这比上面接受的答案要花哨一些。例如,它支持传递环境变量并为您的负载使用 JSON 文件。
【讨论】:
【参考方案5】:如果你只想在本地执行它,你可以使用官方的sam cli
工具
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html
如果你使用 VSCode,你也可以查看这个扩展:
https://marketplace.visualstudio.com/items?itemName=bogdan-onu.invoke
【讨论】:
【参考方案6】:经过一些测试(使用 Node 14.17.3),这可能是最简单的入门方法
let handler = require('./index.js');
handler.handler (
, // event
, // content
(error, result) =>
if (error) console.error(JSON.stringify(error, null, 2));
else console.log(JSON.stringify(result, null, 2));
);
【讨论】:
以上是关于如何使用 NodeJS 在本地测试 AWS Lambda 处理程序?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 NodeJS 在 AWS Lambda 上运行 PhantomJS
在本地测试 Elasticache 和无服务器 AWS Lambda