Migrating an existing REST API (NodeJS/Express) to serverless using Lambda/API Gateway with ClaudiaJS and AWS-Serverless-Express

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- Filament.io 0 Flares ×

Migrating to serverless is a necessary procedure for many companies now, for lowering down the costs of the infrastructure and for increasing reliability of the systems.

The Question

Is it possible to migrate to API Gateway/Lambda a whole application with no effort and maintaining the compatibility with the original machine?

The answer is “yes” and this tutorial explains how it is possible to achieve this goal in minutes and not in weeks.

This tutorial is useful if you

  1. already have a REST API that works on any Linux server or on a cloud such as a AWS EC2.
  2. want to build a new serverless REST API with a complex routing model (not a microservice)
  3. have any NodeJS server side application you want to move to serverless

Prerequisites:

  1. NodeJS
  2. ExpressJS
  3. AWS architecture
  4. Git
  5. AWS CLI

Why to Move a REST API Serverless :

  1. REST APIs made on Express are considered legacy by the most innovative  companies now (Jan 2019), but they are still useful when you have to manage complex queries and routing, and it can be also difficult to cut them into smaller functions so to respect the paradigm of “microservices”.
    The advantages to have Node and Express working on Lambda is that you can also reuse the power of this server-side stack on fast creating new routes and APIs without the need to create a completely new micro API any time you need a new functionality.
  2. AWS Lambda is not meant to work with Express. It simply doesn’t work directly, but this doesn’t mean you cannot move your whole application to it.
  3. Maintaining a classic EC2 based architecture (or any other Linux based machine) is less scalable (see the Figure 1), much more expensive and prone to all the risks due to the management of a complete Linux Stack (web server included). At every update of the operating system or any library on the production machine it is necessary to preventively backup it and to test the updated one again also if you didn’t updated the application stack.
  4. Going serverless is always better than using Load Balancers or Auto Scaling Groups because of costs, deployment time and maintenance risks, but it is usually a long process if the existing stacks are complex:

    This guide will let you reuse the whole code you already made adding only some modifications on the access point and creating just 2 new files.

Fig. 1 - Serverless VS Traditional Stack
Fig. 1 – Serverless VS Traditional Stack

First Step

Your Node/Express application usually has one only access script (typically app.js or index.js or server.js) where the app is instantiated with Express and where it adds the router and manages the listening to a specific port.

In our new application we will have 3 main scripts:

  1. one access point for Lambda (lambda.js) with no port listening
  2. one access point for retrocompatibility and testing (local.js) with the port listening
  3. one real access point called by the previous ones dependently by the environment (app.js)

app.js 

In this script we will add a great library that will do the magic to go serverless with Lambda and Express:

AWS Serverless Express
https://github.com/awslabs/aws-serverless-express

So, first of all, you need to install the library:

 npm install --save aws-serverless-express

Then create the file app.js and fill up the script with the following lines (adding or deleting other parts you added in your original bootstrap file):

////// app.js
////// Your App should use the strict mode:
'use strict'

////// and it should use Express:
const express = require('express')
const app = express()

////// Now you can add aws-serverless-express
const asem = require('aws-serverless-express/middleware')

////// and use it as a middleware in Express:
app.use(asem.eventContext())

////// then you can add your own main router file:
const router = require('./app/route/index')
app.use('/', router)

////// and finally you can manage the errors
function errorHandler(err, req, res, next) {
 res.json({'error': { error: err }})
}
app.use(errorHandler)

////// and export the app
module.exports = app

////// IMPORTANT: do not add app.listen(...)

You can see that we omitted the app.listen(…) part, because Lambda doesn’t use a web server listening to any port. We will add the port listening part to a different file later in this tutorial for compatibility purposes and for testing it in local.

 

lambda.js

Now you have added a new middleware to your Express application and you need to manage it into the Lambda Handler access point.
And here it is where AWS Serverless Express is so useful.

So let’s create a new file called lambda.js and add to it the following lines:

// lambda.js
'use strict'
const ase = require('aws-serverless-express')
const app = require('./app')
const server = ase.createServer(app)
exports.handler = (event, context) => ase.proxy(server, event, context)

As you can see this lambda handler uses the previously created file “app.js” passing to it the exported “app” object

 

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- Filament.io 0 Flares ×