NodeJS Express and AWS Lambda Functions

NodeJS Express and AWS Lambda Functions

In my previous article I wrote about Lambda Function, NodeJS and GitHub Actions. Now, I will share a second article related to "Running a Lambda Express API".

This article assumes that you are familiar with Lambda Function and GitHub Actions. If you are new to Lambda or Github itself, refer first to my previous article call Lambda Functions Challenge.

For this article, you will need:

  • AWS credential for deploy and execution access.
  • GitHub Repository
  • Repository secret with AWS credential loaded: Repository Settings -> Secrets and Variables -> Actions -> New repository secret (we need it for deploy lambda function).


Working with NodeJS

Create express API

Use the npm command to create a new project:

npm init --yes # this will trigger automatically populated initialization with default values        

After that, we are going to install express framework to build the REST API:


npm install express        

Next step, create a new app directory and inside create an app.js file. The project should look like this:

No alt text provided for this image

In the app.js file we add the express server setup:

const express = require('express')
const app = express();
const port = process.env.PORT || 3000;

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.get('/api/v1/hello', (req, res) => {
  res.send({ app: 'aws-lambda-expressjs-nodejs', version: '1.0.0' });
});

app.listen(port, () => console.log(`Listening on: ${port}`));        

Execute the following command to check that everything is ok:

node app/app.js        

Then, visit the url http://127.0.0.1:3000/api/v1/hello and you should get the response bellow:

{
  "app": "aws-lambda-expressjs-nodejs",
  "version": "1.0.0"
}        

Convert our express api to "Lambda Express REST API"

We need to install serverless-http our "serverless wrapper" to make our express app ready to deploy on Lambda Environment:


npm install serverless-http        
This module allows you to 'wrap' your API for serverless use. No HTTP server, no ports or sockets. Just your code in the same execution pipeline you are already familiar with

Now, we are going to add the serverless module and creating a handler for lambda function:

const express = require('express')
// include the serverless-http module
const serverless = require('serverless-http');

const app = express();
const port = process.env.PORT || 3000;

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.get('/api/v1/hello', (req, res) => {
  res.send({ app: 'aws-nodejs-lambda-function', version: '1.0.0' });
});

// comment express server
//app.listen(port, () => console.log(`Listening on: ${port}`));

// add the handler for our lambda function
module.exports.handler = serverless(app);        

From now on, our project is ready to deploy in AWS Lambda environment but before we need to change the function runtime settings and add a trigger type AWS API Gateway (REST).


Runtime Settings

We should be set the handler value with "app/app.handler" since our handler function is located under de directory "app" in "app.js" file.

Go to "Run Time settings" and set the handler value with app/app.js

No alt text provided for this image


API Gateway (REST API)

Create a trigger for add an API Gateway that route HTTP requests to our Lambda function:

No alt text provided for this image


Now, we are going to create a resources in our API Gateway. Go to the API Gateway page, click on Action button and select "Create Resource":

No alt text provided for this image

On "resource path" configuring /{proxy+} as a proxy resource catches all requests to its sub-resources.

Right after that, create an integration between api gateway and lambda function:

No alt text provided for this image

The Api Gateway Resources should look like this:

No alt text provided for this image

At this point, we need to deploy a new version of our Api. Go to the Action button and select deploy option:

No alt text provided for this image

In the stage editor you can find de invoke url (we need it in the final step):

No alt text provided for this image


Create a local environment execution

We need a local environment for develop new features and test the code in our machine. So, in the "scripts" section located the package.json file, add the following command to execute the project as Local Environment using express server:

"local": "APP_ENV=local node app/app.js",        

We passed an APP_ENV environment variable with a value equal "local" for set running express out of serverless module.

Now, we will edit the app.js file and make the following changes:

...
if (process.env.APP_ENV === 'local') {
  app.listen(port, () => console.log(`Listening on: ${port}`));
} else {
  module.exports.handler = serverless(app);
}        

Execute the following command to check that everything is ok:

npm run local        

Then, visit the url http://127.0.0.1:3000/api/v1/hello and you should get the response bellow:

{
  "app": "aws-lambda-expressjs-nodejs",
  "version": "1.0.0"
}        


Pipeline

For this article we are going to create a pipeline using GitHub actions. We need to add a main.yml file under the path ".github/workflows" with the content bellow:

* You should provide the AWS Lambda Function name in the step "Deploy"

name: Deploy

on:
  push:
    branches:
      - master

jobs:
  deploy-lambda:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: '16'
      - name: Install dependencies
        run: npm ci --ignore-scripts
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}
      - name: Deploy
        run: |
         zip -r deploy.zip .
         aws lambda update-function-code --function-name=your-lambda-function --zip-file=fileb://deploy.zip        

Now we are all set to deploy our application. So, commit and push the changes to the repository and the pipeline starts automatically. You can see the progress in the Actions option:

No alt text provided for this image


No alt text provided for this image


Now, is time to test our lambda function. Go to the browser, paste de api gateway url and add our express api path:

https://xxxxxx.execute-api.us-east-1.amazonaws.com/default/api/v1/hello

You should get the response bellow:

}
  "app": "aws-lambda-expressjs-nodejs",
  "version": "1.0.0"
}        

Well done, we have a express js running over lambda function  👏 👏


Conclusion

You can get the source files from my GitHub repository and my previous article here

For this very simple example, we used the default values provided from AWS Console. We didn't talk about Api Gateway security (token, certificates, api key, etc) and Lambda functions deployment packages size as well; If our project is larger than 50 MB, we need a extra integration with S3 Bucket.

Fortunately for us, Lambda functions and api gateway has a lot of features and it is well-documented.

Resources

https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html

https://www.npmjs.com/package/serverless-http

https://www.npmjs.com/package/express

htps://www.npmjs.com/package/express

https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-package.html

https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-package.html

https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html

Isaac Saavedra A

Software Engineer | Java, Spring Boot & Node.js Specialist | Scalable Microservices & Cloud Architectures | +8 yrs solving business challenges

3y

Wonderful, the best article about AWS lambda funtions I've ever seen... 👏🏼

Like
Reply
Catherine Astudillo

Agile Practitioner, Agile Coach, Scrum Master, Product Owner

3y

Loved it, very detailed indeed

To view or add a comment, sign in

More articles by Max Martinez Cartagena

  • Deploy AWS Lambda Function using S3 Bucket and GitHub actions

    AWS Lambda offers zip file as a deployment package. The file includes your application code and its dependencies with a…

    6 Comments
  • Lambda functions challenge

    He didn’t have much understand of the serverless offering from cloud providers… Those are the words from the feedback I…

Others also viewed

Explore content categories