2

I have an express app and is deployed via serverless. My stack is just a lambda function + API Gateway. That works and it's accessible on Postman or httpxmlrequest. But if I take out API Gateway piece from the stack, is it possible to still invoke this lambda function using the AWS SDK/cli, somehow do routing by passing in a path (eg: /books) and a method (eg: POST) together with the payload?

I'm new to the AWS ecosystem... just started using serverless + node.

Say I have a simple express app like so:

const serverless = require('serverless-http');
const express = require('express');
const bodyParser = require('body-parser');

const helpersRoute = require('./routes');
const booksRoute = require('./routes/books');

const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use('/', helpersRoute);
app.use('/books', booksRoute);

module.exports.handler = serverless(app);

And this is my serverless config:

service: service-test

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev

functions:
  app:
    handler: index.handler
Vic
  • 369
  • 1
  • 6
  • 13

1 Answers1

1

Yes, it is possible by using the Lambda SDK. Since you are running your function behind an express server though, you will have to pass an event which looks exactly like API Gateway's, so, from the invoked Lambda perspective, it would simply be an API Gateway's call.

You can check the docs to see what an API Gateway event looks like, but, essentially, you only need path and body (in case of POST, PUT, PATCH) requests. If you need query params, etc you can also pass them along.

Make sure you set the InvocationType to RequestResponse

Here's a sample in Node.js:

const lambda = new AWS.Lambda();

await lambda
    .invoke({
      FunctionName: 'FunctionName',
      InvocationType: 'RequestResponse',
      Payload: JSON.stringify({
        path: '/your_path',
      }),
    })
    .promise();

EDIT: The OP was having problems with the way the data comes from a given Lambda function to the Express-based Lambda function, so I decided to add my own configuration for comparison purposes:

const serverless = require('serverless-http');
const express = require('express');
const cors = require('cors');

const app = express();
const bodyParser = require('body-parser');
const routes = require('./routes');

app.use(cors());

app.use(bodyParser.json({ strict: false }));

app.use('/api', routes);

module.exports.handler = serverless(app);

Sample controller method:

const fetchOne = async (req, res) =>
  res
    .status(200)
    .json(await MyService.doSomething(req.body.someField));
Thales Minussi
  • 6,965
  • 1
  • 30
  • 48
  • I tried passing Payload: JSON.stringify({ path: '/your_path', body: JSON.stringify({name: 'harry potter'}) }) and I'm getting req.body as a Buffer instead of a json on the Express side. What is going there? – Vic Jul 17 '19 at 06:32
  • That's interesting: I always get the JSON back. It comes back in an attribute called `Payload` though, which you need to parse. Try something like this: `const result = await lambda .invoke({ FunctionName: 'FunctionName', InvocationType: 'RequestResponse', Payload: JSON.stringify({ path: '/your_path', body: JSON.stringify({name: 'harry potter'}), }), }) .promise();` and finally `console.log(JSON.parse(result.Payload))` and see what you get – Thales Minussi Jul 17 '19 at 06:53
  • well, on my controller, I have a validation check to see if req.body.name exists. So result.Payload in this case would be an error JSON telling me name is required. What is meant is that my lambda is receiving the event.body as a Buffer object, not the response – Vic Jul 17 '19 at 07:20
  • Oh, sorry. I misunderstood your problem. Your index.js looks good to me. I have compared my configuration with yours and everything looks exactly the same (apart from the fact I don't use the urlencoded body parser, but the json parser should outmatch it anyways). I have edited my answer anyways with my configuration so you can compare it against yours. I have also added an example controller – Thales Minussi Jul 17 '19 at 07:36
  • help me resolve https://stackoverflow.com/questions/76093952/how-to-execute-node-express-specific-route-with-lambda-invoke-using-aws-sdk – micronyks Apr 24 '23 at 16:37
  • pls help. How did you resolve your problem. I face same issue. With accepted answer, it still doesn't work. Pls help : https://stackoverflow.com/questions/76100766/calling-aws-lambda-serverless-express-post-method-route-from-javascript-using – micronyks Apr 25 '23 at 14:07