如何向无服务器 invoke local 传递参数

74

我正在开发一个 AWS 无服务器项目,需要在本地测试 Lambda 函数。
我使用 serverless invoke local -f {function_name} 命令来测试不需要请求任何路径或查询参数的 API 调用。
我的问题是如何使用此命令将任何路径或查询参数传递给函数?

示例 serverless 描述

getFoodDetails:
    handler: handler.getFoodDetails
    events:
      - http:
          method: get
          path: /foods/{food_id}
          cors: true
          request:
            parameters:
              paths:
                food_id: true
8个回答

107

数据字符串

正如所说,您可以使用--data选项将字符串数据作为事件传递给您的函数

serverless invoke local -f {function_name} --data '{ "queryStringParameters": {"id":"P50WXIl6PUlonrSH"}}'

数据文件

你还可以传递一个--path到一个包含数据的JSON文件作为event,并在“事件文件”中定义所需的数据。

serverless invoke --function {function_name} --path event_mock.json

你可以通过调用返回事件并将其保存在 JSON 文件中,或者从 Amazon 获取一个。他们提供了一些示例: https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html

请记住,如果同时传递--path--data两个参数,则包含在--path文件中的数据将覆盖使用--data标志传递的数据。

文档: https://serverless.com/framework/docs/providers/aws/cli-reference/invoke#invoke-local


你如何使用文件来完成这个操作?例如:serverless invoke local --function requestUploadURL --data 'imagepath?' - KD.S.T.
这个答案是不完整的。你指定了如何将数据传递给函数,但没有说明如何从event对象中读取数据。根据你从event对象中读取数据的方式,读取数据的方法也会有所不同。 - Bersan

19

我已经尝试了用属性--data的答案,但都没有起作用。
实际上问题在于--data会将一个字符串值传递给框架。因此,如果您在javascript文件中编写:console.log(typeof(event));, 您将得到String而不是Object。这意味着serverless framework无法正确地将输入转换为JSON对象。这就是为什么你会得到undefined的xx错误。

我的解决方案是使用-p(或--path)属性。按照以下步骤执行:

  1. 在控制台当前位置创建一个.json文件,例如:test.json
  2. 在json文件中编写:{"pathParameters":{"food_id":"100"}}
  3. 在js文件中,要获取food_id,请使用event.pathParameters.food_id
  4. 运行命令:sls invoke local -f yourFunction -p test.json

17

使用 --data 并传递任何格式的数据以将其发送到本地 lambda。

字符串数据示例:

serverless invoke --function functionName --stage dev --region us-east-1 --data "hello world"

JSON 数据示例:

serverless invoke --function functionName --stage dev --region us-east-1 --data '{ "property1": "value"}'

来自文件的 JSON 数据示例:

serverless invoke --function functionName --stage dev --region us-east-1 --path lib/data.json

完整的文档可以从这里获取。

希望它有所帮助。


谢谢。我添加了一个API调用示例,请问您能否展示如何将food_id传递给它? - Lasitha Yapa
event.pathParameters.food_id 是您需要在 json 中发送数据的格式。这就是它从 API 网关传递到 Lambda 的方式。 - Kannaiyan
无服务器本地调用 -f getFoodDetails --data '{"event.pathParameters.food_id":"f00"}'。我尝试了这个,但是出现了“food_id未定义”的错误。 - Lasitha Yapa
看一下嵌套JavaScript对象的示例。https://hackernoon.com/accessing-nested-objects-in-javascript-f02f1bd6387f - Kannaiyan

10

QueryStringParameters 和 pathParameters 是两种不同的输入类型。

对于前者,接受的响应适合我。

对于后者也基本相同,只需将queryStringParameters替换为pathParameters即可。

sls invoke local -f {function_name} --data '{ "pathParameters": {"id":"1"}}'

9

供日后参考。您的问题可以像这样解决。感谢Kannaiyans提供的JSON示例,我才找到了答案。

sls invoke local -f getFoodDetails --data '{ "queryStringParameters": {"food_id":"123"}}'

2
这里还有一种其他选项。我写了一篇关于这个的博客文章,稍后会在详细介绍之后提供链接。
你需要处理两个基本方面:
1. 通过向处理程序传递事件对象来执行处理程序和业务逻辑 2. 处理对 AWS 服务的请求,以便轻松测试
对于第一个问题,我只是将 Mocha 添加到项目中,并使用单元测试框架作为一种方式,以便能够在 IDE 中点击按钮并使用测试数据执行代码。我也可以进行本地调试、逐步执行代码等等。另外一个好处是,如果像我这样纯粹地设置它来执行代码,您仍然拥有一个可以稍后完善的单元测试套件的开端。
对于第二个问题,更容易解决。有一个名为 aws-sdk-mock 的 npm 模块,它允许您注册特定 AWS 服务和方法(例如 DynamoDB.query 或 S3.putItem)的监听器,并使用您希望的任何响应对该请求进行响应,甚至是错误,以便测试您的代码如何处理不可想象的情况;AWS 服务崩溃。
通过设置这两个元素,我可以本地测试任何我开发的处理程序。最终,您始终需要在云中进行一些集成测试,因为无论多么精心或令人敬畏,都没有本地替代品可以使用您将要使用的实际云服务,但这样可以让您走得更远。
链接:https://serverless.com/blog/serverless-local-development

1

顺便说一下,您可以创建另一个函数,并将要调用的所有测试用例放入其中。

module.exports.testerFunction = () => {
  functionIWatnedToInvoke(para1, para2, para3);
  functionIWatnedToInvoke(para4, para5, para6);
  functionIWatnedToInvoke(para7, para8, para9);
}

那么

sls invoke local --function testerFunction

你可以使用循环和单元测试函数编写其他测试用例。 - Amr

0

使用本地调用的一个挑战是您似乎遇到了调试 Lambda 运行时与 DynamoDB 资源之间的问题。理想情况下,您希望同时调用 Lambda 运行时和实时的 DynamoDB 表。目前,无服务器本地调用和 AWS SAM CLI 都会调用 Lambda 运行时,但不会调用实时的云堆栈。

只要您拥有 Lambda 的 ARN,您就可以使用 Stackery CLI(它是免费的)同时调用 Lambda 运行时和云堆栈。这里有一个例子 debugging a serverless framework lambda


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接