繁体   English   中英

AWS CDK - 如何在本地运行 API 和 Lambdas?

[英]AWS CDK - How to run API and Lambdas locally?

编辑:原来解决方案在文档中。 我安装了标准的普通“sam”,但我需要他们所谓的“公共预览版”又名“sam-beta-cdk”。 安装后,API 可以使用sam-betacdk start-api在本地启动并且运行良好。 虽然我很欣赏建议应该使用纯 TDD 进行开发的答案,但我觉得这种更具交互性的手动模式也很有价值,因为它允许更快地探索问题空间。

我正在尝试使用 API 网关、Lambdas 和 DynamoDB 使用 CDK + Typescript 构建我的第一个应用程序。 我已经构建了几个 Lambda 并部署了它们,它们在 web 上运行良好。但是,我不希望将一分钟长的部署周期和各种相关的 AWS 成本作为我工作流程的一部分。 我想要的是能够在本地测试我的 API。

我一直在努力寻找有关如何执行此操作的文档。 Amazon 似乎建议在这里使用 SAM CLI,这就是我一直在尝试的。

文档声称运行sam local xyz运行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"}和正在运行的控制台中的巨大丑陋堆栈跟踪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 响应”。 到目前为止,这并没有帮助我追查问题:/它似乎确实知道测试是一条路线,因为试图击中其他端点会给出经典的{"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 但这比丑陋的大错误消息还要长,所以我没有。

所以我有三个问题(实际上是一百万个问题,但我不想太厚颜无耻!)

  1. 这实际上是本地测试使用 CDK 制作的应用程序的规范方法吗
  2. 如果是这样,我哪里错了?
  3. 如果不是,更好/正确的方法是什么?

您的文件目录一定有问题。 你的 index.js 在哪里? 如果生成模板.json,目录是否正确? 另外,您在什么目录中执行 Sam local 命令?

测试无服务器应用程序的关键是您不必测试整个应用程序。 您需要依靠 AWS API 网关、dynamodb 和 lambda 完美运行。 您唯一需要测试的是您实现的逻辑。

在这里,您确保您的 function 打印出一些东西并返回 200。这就是您要做的全部。 查看'jest'以测试js。

如果你想测试 cdk,你应该进入https://docs.aws.amazon.com/cdk/latest/guide/testing.html

“在本地运行 Aws”也不是好的做法。 它与它在现实生活中(即云)中的运行方式完全不同。 你为此使用插件,为此使用工具......本地与云中不同。

如果您还有其他问题,请随时提问。

Lambda 处理程序只是函数。 它们不需要任何特殊环境到 function - 它们在 Lambda 调用过程中的特定点被调用,并提供一个事件(一个 json 对象)和一个上下文(另一个 json 对象)

您可以(并且应该)像您的语言/测试框架中的任何其他个体 function 一样对它们进行单元测试。

正如@Lucasz 所提到的,您应该依赖这样一个事实,即如果设置正确,API 网关和 Lambda 每次都会以相同的方式进行交互。 一旦你运行了一个端到端测试并且你知道基础工作,任何进一步的实现都可以通过单元测试来完成

在单元测试中有许多用于 mocking AWS 服务调用的库,对于更难模拟的服务有很多好的实践解决方法(即:很难从另一个 lambda 内部模拟 Lambda 调用 - 但如果你包装那个 lambda 调用它自己的 function,你可以模拟 function 本身返回你想要的任何东西 - 这也是测试的好习惯!)

使用开玩笑,在编码单元测试中,您可以调用 lambda 处理程序,给它存根或模拟事件 json,以及上下文 json(可能只是空白,因为您没有使用它)并且 lambda 处理程序将像任何其他处理程序一样工作function 有两个你曾经写过的参数,包括返回你想要它返回的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM