Nathan H
Nathan H

Reputation: 346

Using Express as RESTful Gateway for AWS Lambda

I'm currently building an application built on top of AWS lambda functions, and am wanting to use Express as a middleware and gateway for requests that will then be passed to lambda.

However, I'm wondering if there is any risk in my setup below. Basically, I am defining all the acceptable routes, using router.all('/*') to catch every request, and then if the requested route is in the routes object and requested method is correct, it will authenticate the user and then run the lambda function. I will also add logic for authentication, which data to send to lambda, etc.

My questions are:

  1. Is it acceptable to pass the res object to the lambda execution function?
  2. Would it be better to authenticate in a different place, or is it fine to do so within the router.all function?
  3. Are there any concerns with scalability/handling of many requests using this simple framework?

    const express        = require('express');
    const app            = express();
    var AWS = require('aws-sdk');
    
    var router = express.Router();
    
    const routes = {
    'lambdaFunctionA': { 'method' : 'POST', 'data' : 'body'},
    'lambdaFunctionB': {'method' : 'GET', 'data' : 'queryParams'},
    'lambdaFunctionC': {'method' : 'GET'}
    }
    
    router.all('/*', function (req, res) {
    
      const path = req.path.split('/')[1];
    
      if (path in routes) {
    
        if ( routes[path].method == req.method ) {
            //authentication logic here 
            //if authenticated, execute lambda
            executeLambda(path,someDataHere, res);
        }
        else
        {
            res.status(405).send('Method not allowed');
        }
      }
      else
      {
          res.status(404).send('Not found');
      }
    });
    
    app.use('/api', router);
    
    app.listen(8080);
    
    function executeLambda(functionName,payload, res) {
    
        var params = {
          FunctionName: functionName,
          Payload: payload
        };
    
        var lambda = new AWS.Lambda();      
        lambda.invoke(params, function (err, data) {
          if (err) {
            //need to handle errors here
            res.send(err.stack);
          } else {
            res.send(JSON.parse(data.Payload));
          }
        });
    }
    

Upvotes: 1

Views: 1679

Answers (1)

powerc9000
powerc9000

Reputation: 2103

Why not use express's builtin functionality to do this instead of doing yourself? No need to invent your own routing when express comes with it built-in

function lambdaHandler(req, res){
    executeLambda(path, someDataHere, res);
}
function auth(next){
    //...Do auth stuff
   if(!auth) return next("router");
   next();
}
router.use(auth);
router.post("/lambdaFunctionA", lambdaHandler)
router.get("/lambdaFunctionB", lambdaHandler)
router.get("/lambdaFunctionC", lambdaHandler)

Lookup express middleware

This way you get Express to handle the methods etc for you instead of having to handle it yourself. It can also validate.

And on every request it uses the middleware from router.use(auth) to authenticate before it ever gets to lambdaHandler

Also it is perfectly fine to pass res to the lambda handler. It's just an object.


As a side note:

Have you seen AWS API Gateway?

It can handle routing and uses lambdas just like in your use case. Without having to manage your own server.

Upvotes: 3

Related Questions