Building a Serverless Application with Node.js and AWS Lambda

Serverless architectures are an alternative to high-maintenance, resource-wasting servers. With serverless deployments, you only pay for what you use. It saves you from having to deal with multiple server setups and their configurations.

So it’s no surprise that today’s developers flock to serverless applications. With AWS Lambda and serverless frameworks, you can quickly deploy scalable applications.

How do NodeJS and AWS Lambda go serverless? In this tutorial, we’ll look at deploying a simple serverless API using Node.js, AWS Lambda, and serverless frameworks.


Some information about these technologies

AWS Lambda is a cloud-based, serverless service. A Lambda function is a stateless function that is triggered by an event and expires at the end of execution.

Given the complexity of AWS Lambda, we use a serverless framework to simplify the deployment process. In fact, with Serverless, you can deploy a Node application in just a few steps.


Prerequisite

To continue this tutorial, you’ll need to set up the following.

  • An AWS account. If you’re just trying to use AWS, you don’t have to pay a dime to join the free tier.
  • Create an IAM user in your AWS console. Follow the steps below to create an IAM user in this post. Before you move on to the next step, remember to save the access key ID and secret access key.

Install and set up serverless

NodeJS and AWS Lambda Implementing Serverless Tutorial: You can easily install Serverless using npm. Run the following command to install globally.

npm install -g serverless

Next, use the following command to configure the installed serverless with an IAM key. Use the ID and key saved when creating the IAM user as the key and secret, respectively.

sls config credentials --provider aws --key xxx --secret xxx

Create a Node application

How do NodeJS and AWS Lambda go serverless? I’ve created a simple Hello World app for this tutorial, but you can deploy a more complex app with the same logic.

const express = require("express");
const sls = require("serverless-http");
const app = express();

app.get("/", (req, res) => {
    res.send("Hello World");
});

app.get("/:userName", (req, res) => {
    res.send(`Welcome, ${req.params.userName}`);
})

module.exports.handler = sls(app);

NodeJS implements serverless sample parsing – As you can see above, we use the npm package to set up a serverless application, so make sure you have that package installed. You can install the library using the following command:serverless-http

npm install --save express serverless-http

Create a serverless.yml file

We use a file called serverless.yml to pass the serverless configuration. For our simple application, it contains the following attributes.

service: node-serverless-app

provider: 
  name: aws 
  runtime: nodejs10.x
  stage: dev 
  region: eu-central-1 

functions: 
  app: 
    handler: app.handler 
    events: 
      - http: 
          path: / 
          method: ANY 
      - http: 
            path: /{proxy+} 
            method: ANY 

Here the property lists all the features in our app. We pass a single function called and use the exported reference to the handler in the file as the function handler.functionsappapp.js

Then, we need to add the events that will trigger the given function. We pass HTTP requests as triggering events. I’ve set up in the config above to call the app function every time an HTTP request is sent.

Using Forward Per Request allows the Express application to process each request on its own, rather than processing the request at the API gateway level./{proxy+}


Deploy the application

Now that we’ve passed our configuration to deploy the application, it’s just a matter of command.serverless.yml

sls deploy


Congratulations! You’ve successfully deployed your first serverless application to AWS.

You can access the deployed application through the link provided under the endpoint. If you access the root, you will see the message “Hello World”.


Path-specific routing

NodeJS and AWS Lambda Implementing Serverless Tutorial: Remember how we proxied all the routes to the Express application? While there are many benefits to this implementation, such as limiting cold starts, we miss out on some of the benefits of serverless architecture features.

Instead of using one Lambda function to route all paths, we can introduce path-specific routes that are handled by different Lambda functions. It allows us to better understand the application using path-specific metrics.

NodeJS implementation serverless example – in this case, update like this so that different functions handle each path.serverless.yml

functions: 
  helloWorld:
    handler: app.handler
    events:
      -http:
        path: /
        method: get
  welcome:
    handler: app.handler
    events: 
      -http:
        path: /{userName}
        method: get

Add environment variables

How do NodeJS and AWS Lambda go serverless? You can use this property if you want to pass environment variables to your application.environment

For example, if you want to pass a NODE_ENV variable, you can set it this way.

provider: 
  name: aws 
  runtime: nodejs10.x
  stage: dev 
  region: eu-central-1 
  environment:
   NODE_ENV: production

If you want to pass environment variables from an .env file, you’ll need to use a .serverless-dotenv-plugin

First, install the plugin as a development dependency.

npm install serverless-dotenv-plugin --save-dev

You can then create an .env file in the root directory and add environment variables to it.

STAGE=dev
SECRET=**********

Once the dotenv-plugin is listed under the application plugin, you can import the stored environment variables and use them in the serverless.yml file.

service: node-serverless-app

provider: 
  name: aws 
  runtime: nodejs10.x
  stage: ${env:STAGE}
  region: eu-central-1 
  environment:
   SECRET: ${env:SECRET}

functions: 
  helloWorld:
    handler: app.handler
    events:
      - http:
          path: /
          method: get
  welcome:
    handler: app.handler
    events: 
      - http:
          path: /{userName}
          method: get

plugins:
  - serverless-dotenv-plugin

Use serverless offline

NodeJS and AWS Lambda Implementation Serverless Tutorial: Before that, we had to deploy even our application to perform the simplest routing tests. You only need to write two or three new routes in your application to realize how annoying this is.

What if there was a way to test your application before deploying it to AWS?

By using a serverless offline plugin, you can do just that. All you need to do is install a new npm package and add a new line of code to the serverless.yml file.

NodeJS implementation serverless example – First, install the package.

npm install serverless-offline --save-dev

Then, update the serverless.yml.

plugins:
  - serverless-offline
  - serverless-dotenv-plugin

Now, all you need to do is run the following command to launch the application locally.

sls offline start

It will show you a list of all the routes in the application. Also, and most importantly, it launches applications that run locally on port 3000.

You can now test application routing by accessing them using URL http://localhost:3000 on your browser.


Wraparound

How do NodeJS and AWS Lambda go serverless? Serverless architectures are still in their early stages compared to servers. You can count on it to become more powerful and prominent in the coming years. I hope your first experience with serverless and AWS Lambda will entice you to give this technology a chance the next time you’re looking for deployment options.

Thanks for reading!