【问题标题】:Invoke AWS Lambda from a node.js app running on local system not S3从运行在本地系统而非 S3 上的 node.js 应用程序调用 AWS Lambda
【发布时间】:2018-08-11 20:06:16
【问题描述】:

我想从我系统上的 node.js 文件调用 AWS Lambda。我关注Invoking a Lambda Function in a Browser Script 并为未经身份验证的用户创建了一个 Congnito 身份池,并将 IdentityPoolId 嵌入到节点 js 文件中,如下所示:

let AWS = require('aws-sdk');
AWS.config.region = '<my-region>';
let lambda = new AWS.Lambda();
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: '<my-identity-pool-id>'
});

let params = {
    FunctionName: '<my-lambda-function>',
    InvocationType: 'RequestResponse',
    LogType: 'Tail',
    Payload: '{ "name" : "my-name" }'
}

lambda.invoke(params, (err, data) => {
    if (err) {
        console.log(err);
    }
    else {
        if (data.Payload) {
            console.log('my-lambda-function said: ' + data.Payload);
        }
    }
});

我的 Lambda 函数:

exports.handler = function(event, context) {
  context.succeed('Hello ' + event.name);
};

我创建了一个附加了 AWSLambdaExecute、AWSLambdaBasicExecutionRole 和 AmazonCognitoReadOnly 策略的 IAM 角色,我在创建 Lambda 时使用了相同的角色,并且我在 Cognito 中为未经授权的访问创建的身份池中更新了相同的角色。

当我运行 node app.js 时,我得到的只是错误: UnrecognizedClientException:请求中包含的安全令牌无效。

是否有人可以通过在我的本地系统上编写一个简单的 NodeJS 文件而不在 S3 存储桶中上传任何 HTML/CSS/JS 文件并且不使用 AccessKeyID、SecretKeyId、仅使用关联的角色来指出我调用 AWS lambda 的正确方向与 Lambda。

提前致谢。

【问题讨论】:

  • Aws api 网关?
  • 嗨@Darkrum,你建议我在node.js 中使用API​​ Gateway 调用lambda。你知道任何教程显示如何做到这一点?

标签: node.js amazon-web-services aws-lambda


【解决方案1】:

调用 Lambda 函数的方法有很多种。

  • AWS 服务事件(例如:SNS 触发)
  • 通过 AWS API Gateway 创建的 API。
  • Amazon CloudWatch cron 作业
  • 利用 AWS Lambda API 的 API 调用。

如果您的目标是将您的函数用作 API,可以发送和接收请求和响应,您可能应该选择 API Gateway Integration。

API Gateway 上手非常简单。

  • 准备好您的 Lambda 函数。
  • 为 API 设置 IAM 角色和策略以调用 Lambda 函数

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "lambda:InvokeFunction",
                "Resource": "*"
            }
        ]
    }
  • 为 Lambda 函数创建 API 资源

    1. 在 API Gateway 控制台中,创建 API。

    2. 从 API 的根目录创建 /ResourceName 资源。

    3. 根据您的要求创建 GET 或 POST 方法。

    4. 为集成类型选择 AWS 服务并选择您在相应区域中创建的 Lambda 函数。

  • 现在,您可以使用正文映射模板根据您的要求自定义集成请求。

  • 您可以查看API Gateway Integration with Lambda 的详细文档:

    在本节中,我们将引导您完成集成 API 的步骤 使用 AWS 服务和 Lambda 函数的 Lambda 函数 集成类型。

  • 一旦您的测试调用成功,您就可以使用 API_NAME/Dashboard 中的 API 调用 URL,如下所示:

    https://###****.execute-api.us-west-2.amazonaws.com/{APIStageName}/

它可以用作 REST 端点,并且可以在本地从您的 Node js 函数调用。 不要忘记使用 API 密钥为您的 API 启用身份验证。

此外,如果您要在此类环境中使用它,请查看生产清单。

【讨论】:

  • @Parashar 感谢您的回复。我试图使用 aws-api-gateway-client npm 模块通过 API GateWay 调用 lambda 函数。但我得到了一个未定义的响应。我在以下帖子中详细说明了我采取的步骤:stackoverflow.com/questions/49093365/…。你能调查一下吗。谢谢。
【解决方案2】:

我遇到了同样的问题,我能够使用 Kinesis Stream 解决它。 Lambda 函数充当消费者。 您必须为 Lambda 函数创建触发器,如下所示:

  function createTrigger (kinesisArn, lambdaName) {
    // Create params const for trigger
    const params = {
      EventSourceArn: kinesisArn, 
      FunctionName: lambdaName,
      StartingPosition: 'LATEST',
      BatchSize: 100
    }
  
    return new Promise((resolve, reject) => {
      lambda.createEventSourceMapping(params, (err, data) => {
        if (err) reject(err)
        else resolve(data)
      })
    })
  }

每次向 Kinesis 流推送一条新数据时,都会调用您的 Lambda 函数。

这是一个如何在 AWS Kinesis 流上发送数据的示例:

function send(streamName, partition, msg) {
    const params = {
        Data: JSON.stringify(msg), // data you want to send to your Lambda function
        PartitionKey: partition, // an id for each shard
        StreamName: streamName
    }

    return new Promise((resolve, reject) => {
        kinesis.putRecord(params, (err, data) => {
            if(err) reject(err)
            else resolve(data);
        })
    });
}

【讨论】:

    猜你喜欢
    • 2017-03-26
    • 2019-01-22
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2019-06-11
    相关资源
    最近更新 更多