AWS CDK - 如何在本地 运行 API 和 Lambdas?
AWS CDK - How to run API and Lambdas locally?
编辑:原来解决方案在文档中。我安装了沼泽标准正常 'sam',但我需要他们所谓的 'public preview version' AKA 'sam-beta-cdk'。安装后 API 可以在本地使用 sam-betacdk start-api
启动并且运行良好。虽然我很欣赏建议应该使用纯 TDD 进行开发的答案,但我认为这种更具交互性的手动模式也很有价值,因为它允许更快地探索问题 space.
我正在尝试使用 API Gateway、Lambdas 和 DynamoDB 使用 CDK + Typescript 构建我的第一个应用程序。我已经构建了几个 Lambdas 并部署了它们,它们在网络上运行良好。但是,我不希望将一分钟长的部署周期和各种相关的 AWS 成本作为我工作流程的一部分。我想要的是能够在本地测试我的 API。
我一直在努力寻找有关如何执行此操作的文档。 Amazon 似乎推荐使用 SAM CLI here,这就是我一直在尝试的。
文档声称 运行ning sam local xyz
运行s cdk synth
在 ./aws-sam/build
中进行“可能组装”,但我没有看到这方面的证据.相反,我得到的是 sam 找不到 'template.yml' 的投诉。所以我手动 运行 cdk synth > template.yml
在根文件夹中创建一个。然后我运行 sam local start-api
看来开机很开心
然后我尝试使用 CURL 访问我的测试 lambda:curl 'http://127.0.0.1:3000/test'
我在控制台中得到 {"message":"Internal server error"}
和一个巨大的丑陋堆栈跟踪 运行ning sam local start-api
lambda 是这个...
exports.handler = async function() {
console.log("WooHoo! Test handler ran")
return {statusCode: 200, headers: {"Content-Type": "application/json"}, body: "Test handler ran!"}
}
巨大丑陋的堆栈跟踪的开始...
Mounting /home/user/code/image-cache/asset.beeaa749e012b5921018077f0a5e4fc3ab271ef1c191bd12a82aa9a92148782e as /var/task:ro,delegated inside runtime container
START RequestId: 99f53642-b294-4ce5-a1b4-8c967db80ce1 Version: $LATEST
2021-09-15T12:33:37.086Z undefined ERROR Uncaught Exception {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'test'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js","stack":["Runtime.ImportModuleError: Error: Cannot find module 'test'","Require stack:","- /var/runtime/UserFunction.js","- /var/runtime/index.js"," at _loadUserApp (/var/runtime/UserFunction.js:100:13)"," at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
丑陋的巨大堆栈跟踪结束...
Invalid lambda response received: Lambda response must be valid json
所以看起来 sam local start-api
找不到 test
并抛出错误,这意味着 API 网关没有得到有效的 'lambda response'。到目前为止,这并没有帮助我追查问题:/它似乎确实意识到测试是一条路线,因为试图击中其他端点给出了经典的 {"message":"Missing Authentication Token"}
但是尽管我有两个 {"message":"Missing Authentication Token"}
但它很难尝试实现它 functions/test.ts
和编译的 functions/test.js
存在。
我在我的 CDK 堆栈定义中定义了测试路由和处理程序,就像这样...
const testLambda = new lambda.Function(this, "testLambdaHandler", {
runtime: lambda.Runtime.NODEJS_14_X,
code: lambda.Code.fromAsset("functions"),
handler: "test.handler"
})
api.root
.resourceForPath("test")
.addMethod("GET", new apigateway.LambdaIntegration(testLambda))
我考虑过发布我的 template.yml 但那比丑陋的大错误消息还要长所以我没有。
所以我有三个问题(实际上有一百万个问题,但我不想太厚颜无耻!)
- 这实际上是在本地测试使用 CDK 制作的应用程序的规范方法吗
- 如果是这样,我哪里错了?
- 如果不是,better/proper方法是什么?
您的文件目录一定有问题。您的 index.js 在哪里?如果生成 template.json,目录是否正确?
还有你在什么目录下执行Sam本地命令?
测试无服务器应用程序的关键是您不必测试整个应用程序。您需要依靠 AWS API 网关、dynamodb 和 lambda 完美运行。
您唯一需要测试的是您实现的逻辑。
在这里你要确保你的函数打印出一些东西和 returns 一个 200。这就是你所要做的。
查看 'jest' 以测试 js。
如果你想测试 cdk 你应该进入 https://docs.aws.amazon.com/cdk/latest/guide/testing.html
此外,“运行 Aws locally”也不是好的做法。它与现实生活中的 运行 完全不同,也就是云。你这个用插件,那个用工具……本地跟云端不一样。
如果您还有其他问题,请随时提问。
Lambda 处理程序只是函数。它们不需要任何特殊环境即可运行 - 它们在 Lambda 调用过程的特定点被调用,并提供一个事件(一个 json 对象)和一个上下文(另一个 json 对象)
您可以(并且应该!)像在 language/testing 框架中的任何其他单独函数一样对它们进行单元测试。
正如@Lucasz 所提到的,您应该相信这样一个事实,即如果设置正确,API 网关和 Lambda 每次都会以相同的方式进行交互。一旦你有 运行 一个端到端测试并且你知道基础工作,任何进一步的实现都可以通过单元测试完成
有许多库可用于在单元测试中模拟 AWS 服务调用,并且对于更难模拟的服务(即:很难从另一个 lambda 内部模拟 Lambda 调用)有很多好的实践解决方法- 但如果你将 lambda 调用包装在它自己的函数中,你可以将函数本身模拟为 return 任何你想要的 - 这也是测试的好习惯!)
使用 jest,在编码单元测试中,您可以调用 lambda 处理程序,给它存根或模拟事件 json,以及上下文 json(可能只是空白,因为你不是使用它)和 lambda 处理程序将像您曾经编写的具有两个参数的任何其他函数一样运行,包括 return 将您想要的内容 return.
编辑:原来解决方案在文档中。我安装了沼泽标准正常 'sam',但我需要他们所谓的 'public preview version' AKA 'sam-beta-cdk'。安装后 API 可以在本地使用 sam-betacdk start-api
启动并且运行良好。虽然我很欣赏建议应该使用纯 TDD 进行开发的答案,但我认为这种更具交互性的手动模式也很有价值,因为它允许更快地探索问题 space.
我正在尝试使用 API Gateway、Lambdas 和 DynamoDB 使用 CDK + Typescript 构建我的第一个应用程序。我已经构建了几个 Lambdas 并部署了它们,它们在网络上运行良好。但是,我不希望将一分钟长的部署周期和各种相关的 AWS 成本作为我工作流程的一部分。我想要的是能够在本地测试我的 API。
我一直在努力寻找有关如何执行此操作的文档。 Amazon 似乎推荐使用 SAM CLI here,这就是我一直在尝试的。
文档声称 运行ning sam local xyz
运行s cdk synth
在 ./aws-sam/build
中进行“可能组装”,但我没有看到这方面的证据.相反,我得到的是 sam 找不到 'template.yml' 的投诉。所以我手动 运行 cdk synth > template.yml
在根文件夹中创建一个。然后我运行 sam local start-api
看来开机很开心
然后我尝试使用 CURL 访问我的测试 lambda:curl 'http://127.0.0.1:3000/test'
我在控制台中得到 {"message":"Internal server error"}
和一个巨大的丑陋堆栈跟踪 运行ning sam local start-api
lambda 是这个...
exports.handler = async function() {
console.log("WooHoo! Test handler ran")
return {statusCode: 200, headers: {"Content-Type": "application/json"}, body: "Test handler ran!"}
}
巨大丑陋的堆栈跟踪的开始...
Mounting /home/user/code/image-cache/asset.beeaa749e012b5921018077f0a5e4fc3ab271ef1c191bd12a82aa9a92148782e as /var/task:ro,delegated inside runtime container
START RequestId: 99f53642-b294-4ce5-a1b4-8c967db80ce1 Version: $LATEST
2021-09-15T12:33:37.086Z undefined ERROR Uncaught Exception {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'test'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js","stack":["Runtime.ImportModuleError: Error: Cannot find module 'test'","Require stack:","- /var/runtime/UserFunction.js","- /var/runtime/index.js"," at _loadUserApp (/var/runtime/UserFunction.js:100:13)"," at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
丑陋的巨大堆栈跟踪结束...
Invalid lambda response received: Lambda response must be valid json
所以看起来 sam local start-api
找不到 test
并抛出错误,这意味着 API 网关没有得到有效的 'lambda response'。到目前为止,这并没有帮助我追查问题:/它似乎确实意识到测试是一条路线,因为试图击中其他端点给出了经典的 {"message":"Missing Authentication Token"}
但是尽管我有两个 {"message":"Missing Authentication Token"}
但它很难尝试实现它 functions/test.ts
和编译的 functions/test.js
存在。
我在我的 CDK 堆栈定义中定义了测试路由和处理程序,就像这样...
const testLambda = new lambda.Function(this, "testLambdaHandler", {
runtime: lambda.Runtime.NODEJS_14_X,
code: lambda.Code.fromAsset("functions"),
handler: "test.handler"
})
api.root
.resourceForPath("test")
.addMethod("GET", new apigateway.LambdaIntegration(testLambda))
我考虑过发布我的 template.yml 但那比丑陋的大错误消息还要长所以我没有。
所以我有三个问题(实际上有一百万个问题,但我不想太厚颜无耻!)
- 这实际上是在本地测试使用 CDK 制作的应用程序的规范方法吗
- 如果是这样,我哪里错了?
- 如果不是,better/proper方法是什么?
您的文件目录一定有问题。您的 index.js 在哪里?如果生成 template.json,目录是否正确? 还有你在什么目录下执行Sam本地命令?
测试无服务器应用程序的关键是您不必测试整个应用程序。您需要依靠 AWS API 网关、dynamodb 和 lambda 完美运行。 您唯一需要测试的是您实现的逻辑。
在这里你要确保你的函数打印出一些东西和 returns 一个 200。这就是你所要做的。 查看 'jest' 以测试 js。
如果你想测试 cdk 你应该进入 https://docs.aws.amazon.com/cdk/latest/guide/testing.html
此外,“运行 Aws locally”也不是好的做法。它与现实生活中的 运行 完全不同,也就是云。你这个用插件,那个用工具……本地跟云端不一样。
如果您还有其他问题,请随时提问。
Lambda 处理程序只是函数。它们不需要任何特殊环境即可运行 - 它们在 Lambda 调用过程的特定点被调用,并提供一个事件(一个 json 对象)和一个上下文(另一个 json 对象)
您可以(并且应该!)像在 language/testing 框架中的任何其他单独函数一样对它们进行单元测试。
正如@Lucasz 所提到的,您应该相信这样一个事实,即如果设置正确,API 网关和 Lambda 每次都会以相同的方式进行交互。一旦你有 运行 一个端到端测试并且你知道基础工作,任何进一步的实现都可以通过单元测试完成
有许多库可用于在单元测试中模拟 AWS 服务调用,并且对于更难模拟的服务(即:很难从另一个 lambda 内部模拟 Lambda 调用)有很多好的实践解决方法- 但如果你将 lambda 调用包装在它自己的函数中,你可以将函数本身模拟为 return 任何你想要的 - 这也是测试的好习惯!)
使用 jest,在编码单元测试中,您可以调用 lambda 处理程序,给它存根或模拟事件 json,以及上下文 json(可能只是空白,因为你不是使用它)和 lambda 处理程序将像您曾经编写的具有两个参数的任何其他函数一样运行,包括 return 将您想要的内容 return.