【问题标题】:Correct way to call a lambda in serverless (nodejs 8)在无服务器(nodejs 8)中调用 lambda 的正确方法
【发布时间】:2019-04-26 05:18:27
【问题描述】:

我有 read some guides 并且因为我是菜鸟而且也很愚蠢,所以我仍然看不到在 serverless 中正确地在本地调用 Lambda 的方法。

我首先在下面实现了一个非常基本的 lambda 函数:

'use strict';

const AWS = require('aws-sdk');
const Politician = require('../model/politician.js');

const dynamoDb = new AWS.DynamoDB.DocumentClient();

module.exports.put = async (event, context, callback) => {

    const requestBody = new Politician(event.body);
    let response;

    console.log('did we get this far?');

    submit(requestBody)
        .then(res => {
            response = {
                statusCode: 200,
                body: JSON.stringify({
                    message: `Successfully submitted politician with name ${requestBody.name}`,
                    politicianId: res.id
                })
            }
                .catch(err => {
                    console.log(err);
                    response = {
                        statusCode: 500,
                        body: JSON.stringify({
                            message: `Unable to submit candidate with email ${requestBody.name}`
                        })
                    }
                });
        });
};

const submit = politician => {
    console.log('submitting politician: ' + politician.name);

    return new Promise((resolve, reject) => {
        if (politician) {
            resolve(politician);
        } else {
            reject(new Error('it all went bad!'));
        }
    });
};

我还没有使用 DynamoDB,但我想使用它(我只需要先进行基本调用)。

然后我设置了一个非常简单的 Jest 单元测试,它调用上面的 lambda 函数:

'use strict';
const fs = require('fs');
const { promisify } = require('util');
const readFile = promisify(fs.readFile);

const AWS = require('aws-sdk');
const options = {
    region: 'localhost',
    endpoint: 'http://localhost:8000'
};
AWS.config.update(options);
const eventStub = require('../events/graeme.richardson.json');
const { lambda } = readFile('../functions/coxon-put-politician');


describe('Service politicians: mock for successful operations', () => {

    test('Replies back with a JSON response', () => {

        const event = eventStub;
        const context = {};

        const result = lambda.put(event, context);

        result
            .then(data => {
                expect(data).toBeFalsy();
            })
            .catch(e => {
                expect(e).toBe('me');
            });

    });
});

我尝试了各种方法来调用 const result = lambda.put(event, context); 调用 lambda,只使用它的名称,将对象重铸为函数,以及大量其他方法,但我得到的只是错误的变体:

TypeError: Cannot read property 'put' of undefined

      37 |         const context = {};
      38 | 
    > 39 |         const result = lambda.put(event, context);
         |                               ^
      40 | 
      41 |         result
      42 |             .then(data => {

      at Object.put (functions-test/coxon-put-politician.test.js:39:31)

TypeError: lambda is not a function

      37 |         const context = {};
      38 | 
    > 39 |         const result = lambda(event, context);
         |                        ^
      40 | 
      41 |         result
      42 |             .then(data => {

      at Object.lambda (functions-test/coxon-put-politician.test.js:39:24)

我觉得我只是错过了我链接到的指南没有说的一点信息。有谁知道如何让它工作?

我希望很明显,我最终会在 AWS Lambda 上瞄准 node.js 8.1。

谢谢

【问题讨论】:

  • 所以你想从一个 lambda 函数调用一个 lambda 函数?试试这个:stackoverflow.com/questions/31714788/…
  • 你不是菜鸟或傻瓜。解决问题确实需要一些时间和思考,尤其是使用 AWS。可以分享coxon-put-politician 文件吗?
  • @JackMarchetti 不,我绝对不会尝试这样做 - 只是在本地测试 lambda 函数,使用开玩笑的单元测试。
  • @JoseA 抱歉,我的问题不够清楚,第一个代码块是 Lambda 函数,第二个是 Jest 单元测试,它(希望)可以调用 lambda 函数。我可以发布所有其他无服务器项目,但这一切似乎都有效(嗯,按预期部署),我认为这不会增加问题的清晰度。
  • 看起来lambda 不是由readfile 发起的。试试这个const lambda = require('../functions/coxon-put-politician');

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


【解决方案1】:

感谢您查看此@Chetan Ranpariya,是的,这似乎是问题所在。不知道为什么很多帖子都推荐promisify() - 我猜肯定有一种方法可以奏效,但我只是没有魔力。有效的 lambda 代码是:

'use strict';

const AWS = require('aws-sdk');
const Politician = require('../model/politician.js');

module.exports.put = async (event, context) => {

    const requestBody = new Politician(event.body);
    let response;

    submit(requestBody)
        .then(res => {
            response = {
                statusCode: 200,
                body: JSON.stringify({
                    message: `Successfully submitted politician with name ${requestBody.name}`,
                    politicianId: res.id
                })
            }

        });
};

const submit = politician => {
    console.log('submitting politician: ' + politician.name);

    return new Promise((resolve, reject) => {
        if (politician) {
            resolve(politician);
        } else {
            reject(new Error('it all went bad!'));
        }
    });
};

它的 Jest 测试是:

'use strict';
const AWS = require('aws-sdk');
const options = {
    region: 'localhost',
    endpoint: 'http://localhost:8000'
};
AWS.config.update(options);
const eventStub = require('../events/graeme.richardson.json');
const lambda = require('../functions/coxon-put-politician');


describe('Service politicians: mock for successful operations', () => {

    test('Replies back with a JSON response', () => {

        const event = eventStub;
        const context = {};

        const result = lambda.put(event, context);

        result
            .then(data => {
                expect(data).toBeTruthy();
            })

    });
});

【讨论】:

    猜你喜欢
    • 2021-06-16
    • 1970-01-01
    • 2017-01-21
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 2018-08-06
    • 2020-01-21
    相关资源
    最近更新 更多