Skip to content

Building a CRUD Application with Nest.js: A Comprehensive Guide

Introduction

Nest.js is a powerful and scalable Node.js framework that leverages TypeScript to build efficient and maintainable server-side applications. In this article, we will explore how to implement a CRUD (Create, Read, Update, Delete) application using Nest.js. We will cover the fundamental concepts and demonstrate the implementation of each CRUD operation with code examples. By the end, you will have a solid understanding of how to build a fully functional CRUD application with Nest.js.

Prerequisites

Before we dive into the implementation, make sure you have the following prerequisites installed on your machine:

  • Node.js (version 12 or above)
  • npm (Node Package Manager)
  • TypeScript

Step 1: Setting up a Nest.js Application

Let's start by creating a new Nest.js application. Open your terminal and run the following command:

sh
$ npm install -g @nestjs/cli
$ nest new nest-crud-app

Step 2: Creating the Data Model

In this example, let's assume we are building a CRUD application for managing users. We need to define a User data model. Create a new file named user.model.ts in the src directory and add the following code:

typescript
export class User {
id: number;
name: string;
email: string;
}

Step 3: Creating the User Service

Next, let's create a service responsible for handling user-related operations. Run the following command to generate a new service:

sh
$ nest generate service user

This will create a new user.service.ts file in the src directory. Open the file and update it with the following code:

typescript
import { Injectable } from '@nestjs/common';
import { User } from './user.model';

@Injectable()
export class UserService {
  private users: User[] = [];

  getAllUsers(): User[] {
    return this.users;
  }

  getUserById(id: number): User {
    return this.users.find(user => user.id === id);
  }

  createUser(user: User): User {
    user.id = Date.now();
    this.users.push(user);
    return user;
  }

  updateUser(id: number, updatedUser: User): User {
    const userIndex = this.users.findIndex(user => user.id === id);
    if (userIndex >= 0) {
      this.users[userIndex] = { ...this.users[userIndex], ...updatedUser };
      return this.users[userIndex];
    }
    return null;
  }

  deleteUser(id: number): User {
    const userIndex = this.users.findIndex(user => user.id === id);
    if (userIndex >= 0) {
      const deletedUser = this.users[userIndex];
      this.users.splice(userIndex, 1);
      return deletedUser;
    }
    return null;
  }
}

Step 4: Creating the User Controller

Now, let's create a controller to handle incoming HTTP requests and interact with the UserService. Run the following command to generate a new controller:

shell
$ nest generate controller user

This will create a new user.controller.ts file in the src directory. Open the file and update it with the following code:

typescript
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { User } from './user.model';
import { UserService } from './user.service';

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  getAllUsers(): User[] {
    return this.userService.getAllUsers();
  }

  @Get(':id')
    getUserById(@Param('id') id: number): User {
    return this.userService.getUserById(id);
  }

  @Post()
  createUser(@Body() user: User): User {
    return this.userService.createUser(user);
  }

  @Put(':id')
  updateUser(@Param('id') id: number, @Body() updatedUser: User): User {
    return this.userService.updateUser(id, updatedUser);
  }

  @Delete(':id')
  deleteUser(@Param('id') id: number): User {
    return this.userService.deleteUser(id);
  }
}

Step 5: Wiring up the Modules

Open the src/app.module.ts file and update it with the following code:

typescript
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserController } from './user/user.controller';
import { UserService } from './user/user.service';

@Module({
  imports: [],
  controllers: [AppController, UserController],
  providers: [AppService, UserService],
})
export class AppModule {}

Step 6: Testing the CRUD Operations

Now, we have completed the implementation of the CRUD functionality for our user management application. To test the application, open the terminal and run the following command:

shell
$ npm run start:dev

This will start the Nest.js application on the default port (e.g., 3000). You can use tools like Postman or cURL to send HTTP requests and test the CRUD operations:

To retrieve all users, send a GET request to http://localhost:3000/users. To retrieve a specific user by ID, send a GET request to http://localhost:3000/users/{id}. To create a new user, send a POST request to http://localhost:3000/users with the user object in the request body. To update an existing user, send a PUT request to http://localhost:3000/users/{id} with the updated user object in the request body. To delete a user, send a DELETE request to http://localhost:3000/users/{id}.

Conclusion

Congratulations! You have successfully implemented a CRUD application using Nest.js. We explored the key components of Nest.js, such as controllers, services, and modules, and demonstrated how to handle CRUD operations for managing users. You can apply similar principles to expand the functionality of your application and integrate other features as per your requirements. Nest.js provides a robust foundation for building scalable and maintainable server-side applications with TypeScript.

Remember to refer to the official Nest.js documentation for more advanced features and best practices. Happy coding!