Nest.js and AWS Lambda for Serverless Microservices

Nest.js and AWS Lambda for Serverless Microservices

Nest.js and AWS Lambda for Serverless Microservices

Serverless architecture has emerged as a leading paradigm for developing applications that demand scalability, cost efficiency, and ease of management. This article provides a complete guide into serverless microservices, along with the integration of Nest.js, a robust and extensible Node.js framework, with AWS Lambda — a key player in the serverless ecosystem. By combining Nest.js and AWS Lambda, developers can harness the benefits of serverless computing to build flexible, resilient, and highly scalable microservices.

Introduction to Nest.js

Nest.js stands out as a versatile and opinionated framework for building server-side applications with Node.js. It embraces the architectural patterns of Angular, making it particularly suitable for developers familiar with the Angular framework. Nest.js combines elements of both object-oriented programming and functional programming, offering a well-organized structure and an integrated development experience.

Key Features of Nest.js

Modularity: Nest.js encourages a modular structure, facilitating the organization of code into reusable and maintainable modules.

Dependency Injection: Using TypeScript, Nest.js utilizes dependency injection to enhance code maintainability and testability.

Decorators and Metadata: The framework employs decorators and metadata reflection to simplify the creation of controllers, services, and modules.

Middleware Support: Nest.js also supports the use of middleware for handling requests and responses, enabling the creation of custom processing logic.

WebSockets and Microservices: Provides built-in support for WebSockets and facilitates the creation of microservices, aligning with the demands of modern, real-time applications.

Key Features of AWS Lambda

AWS Lambda is a serverless computing service within Amazon Web Services (AWS), designed to enable code execution without the hassle of server provisioning. Embracing an event-driven model, it responds to events and dynamically scales based on demand. Its support for various programming languages, including Node.js, positions it as an excellent choice for deploying Nest.js applications.

Usage-Based Billing: AWS Lambda operates on a pay-as-you-go billing model, ensuring charges are directly tied to the compute time your code utilizes.

Event-Driven Architecture: Lambda functions respond to diverse triggers, including AWS services, HTTP requests, or custom events. This adaptability facilitates smooth integration into the wider AWS ecosystem.

Automatic Scaling: Lambda effortlessly scales to manage incoming requests, maintaining optimal performance without manual intervention.

API Gateway Integration: Lambda functions can be easily exposed as HTTP endpoints through AWS API Gateway, establishing a scalable and managed API layer.

Installing Nest.js CLI Globally

Before proceeding with developing serverless microservices using Nest.js, we need to have the Nest.js Command Line Interface (CLI) installed globally on our machine. This will allow us to simplify the process of creating, managing, and deploying Nest.js applications.

On your terminal, run the following command to install the Nest.js CLI globally:

Once the installation is complete, verify the installation by running:

This should display the installed version of the Nest.js CLI. We are now ready to create a project for building serverless microservices.

Creating a New Nest.js Project

We will use Nest.js CLI to set up a Nest.js project that we will use to build a Lambda for serverless microservices. On your terminal run the following command to generate a new Nest.js project:

This command will walk you through the process of selecting a package manager (e.g., npm or yarn) and allow you to configure the project based on your choices.

Understanding the Nest.js Project Structure

A Nest.js project structure relies on several key files and directories that play integral roles in the application’s functionality.

Create a new Nest.js project to see the essential files and directories to form the basis of your application

Create a new Nest.js project to see the essential files and directories to form the basis of your application

src Directory: Within this directory, the main.ts file stands as the entry point of your Nest.js application. This file takes on the responsibility of initializing the Nest application, configuring global middleware, and initiating the server.

app.module.ts: Considered the primary module of your application, this file orchestrates the various modules, controllers, and services that compose your Nest.js project.

app.controller.ts and app.service.ts (or equivalent): Within these files, you’ll find a fundamental illustration of a Nest.js controller and service. Controllers manage incoming requests, while services encapsulate the application’s business logic.

nestjs-cli.json and nest-cli.json (or nestconfig.json): These configuration files belong to the Nest.js CLI, defining settings like the root directory and the source code directory. They play a crucial role in influencing how the CLI interacts with your project.

package.json and package-lock.json: Standard Node.js project files that define dependencies and scripts crucial for managing the project.

tsconfig.json: This TypeScript configuration file outlines compiler options and project settings, ensuring the proper compilation and execution of the TypeScript code.

test Directory: Within this directory, you can find files and configurations specifically tailored for testing your Nest.js application. This section is essential for ensuring the robustness and reliability of your codebase.

Running the Project

In the terminal, move to the project directory:

Initiate the development server:

This script compiles the TypeScript code and initiates the Nest.js application in development mode. Access http://localhost:3000 through your web browser to view the default welcome message.

Understanding the Flow

Let’s take a closer look at the main.ts file, which plays a crucial role in setting up your Nest.js application:

The NestFactory.create(AppModule) method creates a new instance of the Nest application, initializing the AppModule.

Open the src/app.controller.ts file in your code editor.

The @Get() decorator defines an HTTP GET endpoint at the root path (‘/’). The getHello() method invokes the getHello() method from the AppService class.

Next, check out the src/app.service.ts file:

The AppService class contains a simple getHello() method that returns the “Hello World!” message.

When you access localhost:3000 in your browser, the getHello() method in AppController is executed. This method, in turn, calls the getHello() method in AppService class, returning the "Hello World!" message

When you access localhost:3000 in your browser, the getHello() method in AppController is executed. This method, in turn, calls the getHello() method in AppService class, returning the “Hello World!” message

Feel free to explore and modify these files to suit your project requirements. As you build serverless microservices, keep in mind that AWS Lambda deployment involves adapting your application to work within the constraints of serverless architecture.

Now that our Nest.js project is up and running locally, we are now ready to proceed with building serverless microservices and deploying them on AWS Lambda.

Creating User Module

In this section, we will create a User module to handle user-related operations using Nest CLI. The User Module in Nest.js centralizes functionalities related to user management, encompassing a controller for handling HTTP requests, a service for business logic.

The command nest generate resource user sets up the basic structure for the User module

The command nest generate resource user sets up the basic structure for the User module

Next, install the required dependencies for database access:

We will use TypeORM, a powerful tools for performing database operations, defining entities, and managing relationships between them.

Next, implement the User entity using TypeORM to define the user’s data structure. This modular organization enhances code maintainability and scalability.

Update the entity file (user.entity.ts):

To enable the module to work with the entity, add an import to the module definition (user.module.ts):

Now, implement the service layer in the user.service.ts file:

To keep things simple, we’ll use the User entity as a DTO. Update the controller and service in user.controller.ts:

Now we will create a Database named usersapi and define a user table within it by executing the following script in your local MySQL environment.

Ensure the API can connect to it by updating the configuration in app.module.ts:

Run the application using npm run start and test it by sending requests to create, list, and remove users.

Run and Test the Users API

Let’s test the API by sending some requests. Use curl commands to interact with the API endpoints. Here’s an example of creating a new user:

The response will provide details about the created user, including the user ID.

Now trying retrieving a list of all the created users:

In return, you will receive an array of user objects with their respective data.

In order to fetch details of a specific user by ID, use the following command (replace {user_id} with an actual user ID):

If you want to delete a user, you can use the following command (replace {user_id} with the ID of the user to be deleted):

By testing these requests locally, we have ensured that the Users API is functioning correctly before deploying it to the cloud.

Setting Up AWS CLI

Before taking your Nest.js application to AWS Lambda, make sure you’ve got your AWS account in place, and your credentials are correctly set up.

On Windows, setting environment variables is accomplished using the set command and the export command is used in Unix-based systems. Follow these steps to set the AWS_PROFILE environment variable:

Replace profile-name with your AWS profile name. This sets the AWS_PROFILE variable for the current command prompt session.

AWS CLI Installation and Configuration

Install the AWS CLI from here. Open the command line and run the following:

Enter your AWS Access Key ID, Secret Access Key, default region, and output file format when prompted. Your credentials file will be stored in the following directory:

With content similar to:

The configuration step is important for secure and efficient communication between your system and AWS services, enabling the development and deployment tasks.

Setting up an SQL-based RDS Database

Amazon RDS (Relational Database Service) is a managed relational database service by AWS that simplifies database setup, operation, and scaling. It supports multiple database engines, including MySQL, which we will use in this example.

Use the following CloudFormation template (rds.yaml) to define an RDS instance. Adjust the parameters, including MasterUsername and MasterUserPassword for security:

Deploying the CloudFormation Stack

Save the rds.yaml file and run the following command to deploy the CloudFormation stack, creating the RDS instance:

Replace your-preferred-region with the code for your desired AWS region (e.g., us-east-1 or eu-west-1).

The process can take few minutes, and once done, you will receive a success message on your command line

The process can take few minutes, and once done, you will receive a success message on your command line

Obtaining Database URL and Configurations

Once the RDS database is ready, follow either of the below mentioned steps:

  • AWS Console: Navigate to the AWS RDS Console, locate your database instance, and find its details, including the endpoint URL.
  • AWS CLI and CloudFormation: Use the AWS CLI to list the exports of the CloudFormation stack. Look for values related to your RDS instance, including the endpoint URL.

With the obtained database URL, update your local project’s app.module.ts file to configure the connection settings. Ensure your local application can connect to the remote AWS RDS instance for seamless development and testing.

Cloud Deployment with Serverless

Next, install Serverless Framework CLI globally.

For deployment configuration, create a serverless.yaml file in the project root with all the necessary settings. This file defines deployment details for the Serverless Framework, specifying AWS as the provider and setting up functions.

Additionally, install serverless-jetpack as it efficiently packages your app for Serverless deployment. Also, include serverless-express as it adapts Express-based apps for Lambda environments, ensuring compatibility and efficient execution during deployments.

Finally, create a lambda_api.ts file in the source folder. This file serves as the Lambda handler function, facilitating the integration of your Nest.js application with the AWS Lambda service. The handler function, defined in this file, enables seamless communication between the AWS Lambda environment and your Nest.js app.

Build your Nest.js application.

Now you are all set to deploy your API to the cloud using Serverless.

Once the deployment is complete, you will receive a unique URL, such as https://your-unique-id.execute-api.your-region.amazonaws.com.


Interact with your serverless API using this URL. Test with different requests to test its functionality.

Diagrammatic flow of Nest.js and AWS Lambda Integration

Explore the visual representation of the end-to-end process, providing a comprehensive overview of Nest.js and AWS Lambda integration for serverless microservices.

Conclusion

Nest.js coupled with AWS Lambda is a robust combination for building serverless microservices. Nest.js simplifies development, AWS Lambda provides cost-effective serverless computing, and the Serverless Framework streamlines deployment. This approach also paves way for rapid development, maintainability, and automatic scaling, making it an ideal choice for crafting efficient and scalable microservices.

Download

Sources:

About the author

Stay Informed

It's important to keep up
with industry - subscribe!

Stay Informed

Looks good!
Please enter the correct name.
Please enter the correct email.
Looks good!

Related articles

26.02.2024

Server-Side Rendering with Vue.js and Nuxt.js

Vue.js and Nuxt.js seamlessly complement each other for SSR. Vue.js provides the core functionality for dynamic UIs, while Nuxt.js enables ...

Profiling Tools and Techniques for Node.js Applications

A well-optimized Node.js application not only ensures a smoother user experience but also scales effectively to meet ...

13.02.2024

Mastering N-API and Native Modules in Node.js

Central to the development of Node native modules is Node-API, a groundbreaking toolkit introduced since Node.js 8.0.0. Node-API serves as an ...

No comments yet

Sign in

Forgot password?

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy

Password recovery

You can also try to

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy