'Routing in a lambda function without API Gateway

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


Solution 1:[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));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1