DEV Community

Cover image for Building a Scalable API with NestJS: A Comprehensive Guide
3a5abi 🥷
3a5abi 🥷

Posted on • Originally published at devtoys.io

Building a Scalable API with NestJS: A Comprehensive Guide

NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. Leveraging TypeScript, it integrates elements from modern frameworks such as Angular to create a robust development experience. This tutorial will guide you through creating a simple, yet comprehensive API using NestJS, touching on its core concepts and demonstrating how to implement various features.

Prerequisites – NestJS

Before we dive into NestJS, ensure you have the following installed:

  • Node.js (version 12 or higher)
  • npm or yarn
  • TypeScript

Step 1: Setting Up Your NestJS Project – NestJS

Start by installing the NestJS CLI globally:

npm install -g @nestjs/cli
Enter fullscreen mode Exit fullscreen mode

Create a new project using the CLI:

nest new my-nestjs-app
Enter fullscreen mode Exit fullscreen mode

Navigate to your project directory:

cd my-nestjs-app
Enter fullscreen mode Exit fullscreen mode

👀 Checkout the original ariticle here plus more! ===> Building a Scalable API with NestJS: A Comprehensive Guide - DevToys.io


Step 2: Understanding the Project Structure - NestJS

NestJS projects follow a modular architecture. Here's a brief overview of the default structure:

src/: Contains your application's source code.

app.controller.ts: Handles incoming requests and returns responses.

app.service.ts: Contains the business logic.

app.module.ts: The root module of the application.

test/: Contains the testing files.

main.ts: The entry point of the application.
Enter fullscreen mode Exit fullscreen mode

Step 3: Creating Your First Module - NestJS

Modules are fundamental building blocks of a NestJS application. Create a new module called users:

nest generate module users
Enter fullscreen mode Exit fullscreen mode

This will generate a users directory inside the src folder with a users.module.ts file.


Step 4: Creating Controllers and Services

Controllers handle incoming requests and return responses, while services contain the business logic. Generate a controller and service for the users module:

nest generate controller users
nest generate service users
Enter fullscreen mode Exit fullscreen mode

Step 5: Implementing the Users Service

Open src/users/users.service.ts and implement basic CRUD operations:

import { Injectable } from '@nestjs/common';

export interface User {
  id: number;
  name: string;
  age: number;
}

@Injectable()
export class UsersService {
  private readonly users: User[] = [
    { id: 1, name: 'John Doe', age: 30 },
    { id: 2, name: 'Alice Caeiro', age: 20 },
    { id: 3, name: 'Who Knows', age: 25 },
  ];

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

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

  create(user: User) {
    this.users.push(user);
  }

  update(id: number, updatedUser: User) {
    const userIndex = this.users.findIndex((user) => user.id === id);
    if (userIndex > -1) {
      this.users[userIndex] = updatedUser;
    }
  }

  delete(id: number) {
    const index = this.users.findIndex((user) => user.id === id);
    if (index !== -1) {
      this.users.splice(index, 1);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Implementing the Users Controller

Open src/users/users.controller.ts and connect the service to handle HTTP requests:

import { Controller, Get, Post, Put, Delete, Param, Body } from '@nestjs/common';
import { UsersService, User } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  findAll(): User[] {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string): User {
    return this.usersService.findOne(+id);
  }

  @Post()
  create(@Body() user: User) {
    this.usersService.create(user);
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() user: User) {
    this.usersService.update(+id, user);
  }

  @Delete(':id')
  delete(@Param('id') id: string) {
    this.usersService.delete(+id);
  }
}
Enter fullscreen mode Exit fullscreen mode

** Fun Fact: the + in +id is a unary plus operator that converts a string to a number in JavaScript and TypeScript! FUN! 🤓 **


Step 7: Integrating the Users Module

Ensure the UsersModule is imported in the root AppModule. Open src/app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';

@Module({
  imports: [UsersModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Step 8: Running the Application

Start the application:

npm run start
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:3000/users to see your API in action.

Conclusion

Congratulations! You've created a basic NestJS API with CRUD functionality. This tutorial covers the foundational concepts of NestJS, but there's much more to explore. NestJS offers powerful features like dependency injection, middleware, guards, interceptors, and more.

Dive into the official documentation to continue your journey and build more advanced applications with NestJS. Happy coding!

👀 If you are interested in more articles like these, come join our community at DevToys.io!

Top comments (0)