Menu Close

How to Build an API with NestJS

NestJS is a progressive Node.js framework that provides a robust foundation for building efficient and scalable server-side applications. With its modular architecture and dependency injection system, NestJS simplifies the process of creating APIs for web services. In this article, we will explore the key steps and best practices involved in building an API with NestJS, focusing on creating endpoints, handling requests and responses, implementing authentication, and optimizing performance. By following these guidelines, developers can leverage the power of NestJS to efficiently develop powerful and reliable APIs for their web services.

Building a powerful and scalable API with NestJS can significantly enhance your web service offerings. NestJS is a progressive Node.js framework that leverages the power of TypeScript, making it ideal for building efficient, testable, and scalable applications. In this guide, we will walk through the steps to create a fully functional RESTful API using NestJS.

Prerequisites

Before diving into building your API, ensure you have the following:

  • Node.js installed (preferably version 14 or later).
  • NPM (Node Package Manager), which comes with Node.js.
  • Basic knowledge of TypeScript and Node.js.
  • A code editor such as Visual Studio Code.

Setting Up Your NestJS Project

First, you need to install the NestJS CLI and create a new project. Open your terminal and run the following commands:

npm install -g @nestjs/cli
nest new my-nest-api

Replace my-nest-api with your desired project name. This command will create a new directory with the specified name and initialize a NestJS project within it.

Understanding the Project Structure

Once your project is created, navigate into the project directory and explore its structure:

cd my-nest-api

The important directories and files include:

  • src/: Contains the application source code.
  • app.module.ts: The root module of your application.
  • main.ts: The entry point of your Nest application.

Creating Your First RESTful API

In this section, we will build a simple RESTful API for managing tasks in a to-do application.

Step 1: Generate a Module and Controller

Use the NestJS CLI to generate a new module and a controller:

nest generate module tasks
nest generate controller tasks

This will create a tasks directory within the src folder containing the module and controller files.

Step 2: Build the Tasks Service

Next, let’s create a service that will handle business logic:

nest generate service tasks

This service will manage the tasks, including creating, retrieving, updating, and deleting tasks. Open the tasks.service.ts file and implement the basic CRUD operations:


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

export interface Task {
    id: number;
    title: string;
    description: string;
}

@Injectable()
export class TasksService {
    private tasks: Task[] = [];
    private idCounter = 1;

    create(title: string, description: string): Task {
        const task = { id: this.idCounter++, title, description };
        this.tasks.push(task);
        return task;
    }

    findAll(): Task[] {
        return this.tasks;
    }

    findOne(id: number): Task {
        return this.tasks.find(task => task.id === id);
    }

    update(id: number, title: string, description: string): Task {
        const task = this.findOne(id);
        task.title = title;
        task.description = description;
        return task;
    }

    delete(id: number): void {
        this.tasks = this.tasks.filter(task => task.id !== id);
    }
}

Step 3: Implement the Tasks Controller

Now, let’s implement the tasks.controller.ts file to handle incoming requests:


import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { TasksService, Task } from './tasks.service';

@Controller('tasks')
export class TasksController {
    constructor(private readonly tasksService: TasksService) {}

    @Post()
    create(@Body('title') title: string, @Body('description') description: string): Task {
        return this.tasksService.create(title, description);
    }

    @Get()
    findAll(): Task[] {
        return this.tasksService.findAll();
    }

    @Get(':id')
    findOne(@Param('id') id: number): Task {
        return this.tasksService.findOne(id);
    }

    @Put(':id')
    update(@Param('id') id: number, @Body('title') title: string, @Body('description') description: string): Task {
        return this.tasksService.update(id, title, description);
    }

    @Delete(':id')
    delete(@Param('id') id: number): void {
        this.tasksService.delete(id);
    }
}

Step 4: Register the Module

Open the app.module.ts file and register your newly created module:


import { Module } from '@nestjs/common';
import { TasksModule } from './tasks/tasks.module';

@Module({
    imports: [TasksModule],
})
export class AppModule {}

Testing Your API

After implementing the tasks API, you can run your application by executing:

npm run start

Your API will be accessible at http://localhost:3000/tasks. Use tools like Postman or curl to test the various endpoints:

  • Create a Task: Send a POST request to http://localhost:3000/tasks with a JSON body containing {"title": "Test Task", "description": "This is a test."}
  • Retrieve All Tasks: Send a GET request to http://localhost:3000/tasks
  • Retrieve a Task by ID: Send a GET request to http://localhost:3000/tasks/1
  • Update a Task: Send a PUT request to http://localhost:3000/tasks/1 with a JSON body containing updated details
  • Delete a Task: Send a DELETE request to http://localhost:3000/tasks/1

Implementing Validation and Error Handling

To ensure your API is robust, you should implement validation and error handling. Use class-validator and class-transformer libraries for DTO (Data Transfer Objects) validation.

Step 1: Install Required Packages

Run the following command to install the necessary packages:

npm install class-validator class-transformer

Step 2: Create DTOs

Create a new folder called dto in the tasks directory, and create a simple DTO for tasks:


import { IsNotEmpty, IsString } from 'class-validator';

export class CreateTaskDto {
    @IsString()
    @IsNotEmpty()
    title: string;

    @IsString()
    @IsNotEmpty()
    description: string;
}

Step 3: Use DTOs in the Controller

Update your controller to use the DTO for creating tasks:


import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { TasksService, Task } from './tasks.service';
import { CreateTaskDto } from './dto/create-task.dto';

@Controller('tasks')
export class TasksController {
    constructor(private readonly tasksService: TasksService) {}

    @Post()
    create(@Body() createTaskDto: CreateTaskDto): Task {
        return this.tasksService.create(createTaskDto.title, createTaskDto.description);
    }
    // Other endpoints remain unchanged
}

Documenting Your API with Swagger

Documenting your API is essential for improving usability and engagement. NestJS integrates seamlessly with Swagger, providing an easy way to generate documentation from your code.

Step 1: Install Swagger Package

npm install @nestjs/swagger swagger-ui-express

Step 2: Configure Swagger

Add the following configuration in the main.ts file:


import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);

    const options = new DocumentBuilder()
        .setTitle('Tasks API')
        .setDescription('API for managing tasks')
        .setVersion('1.0')
        .build();
    const document = SwaggerModule.createDocument(app, options);
    SwaggerModule.setup('api', app, document);

    await app.listen(3000);
}
bootstrap();

Now, after running your application, navigate to http://localhost:3000/api to view your Swagger documentation.

Conclusion

Building an API with NestJS allows for rapid development and clean organization of your code. The framework provides powerful tools and an elegant structure that makes it easy to build and maintain APIs. By following the steps outlined in this guide, you can create a robust RESTful API, implement validation, and deliver comprehensive documentation. As you continue to explore NestJS, you’ll discover even more features that can enhance your API with authentication, protection layers, and integrations with various databases.

Building an API with NestJS provides a powerful framework for creating scalable and maintainable web services. Its modular approach, dependency injection, and built-in support for features such as authentication, validation, and error handling make it a robust choice for developing APIs. By leveraging NestJS, developers can streamline the API development process and ensure a solid foundation for building reliable and efficient web services.

Leave a Reply

Your email address will not be published. Required fields are marked *