Getting Started with NestJS: Your First REST API
Enock OmondiIntroduction
NestJS has been gaining popularity among developers for building efficient, scalable, and maintainable server-side applications. In this comprehensive guide, we'll walk through the process of setting up your first REST API using NestJS.
Whether you're new to backend development or coming from other Node.js frameworks, this tutorial will help you get up and running with NestJS quickly.
What is NestJS?
NestJS is a progressive Node.js framework for building efficient and scalable server-side applications. It uses modern JavaScript features and is built with TypeScript, which brings a superior developer experience. NestJS leverages Express.js under the hood but provides a more opinionated and structured approach to application architecture.
Key features of NestJS include:
- Dependency Injection
- Decorators for defining routes and middleware
- TypeScript support out of the box
- Modular architecture
- Easy integration with various databases and ORMs
Prerequisites
Before we begin, make sure you have the following installed on your system:
- Node.js (version 12 or later)
- npm (Node Package Manager)
Setting Up Your NestJS Project
Let's start by creating a new NestJS project. Open your terminal and run the following commands:
npm i -g @nestjs/cli
nest new nestjs-rest-api
cd nestjs-rest-api
Project Structure
After creating your project, you'll see a folder structure similar to this:
nestjs-rest-api/
├── src/
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ └── main.ts
├── test/
├── node_modules/
├── package.json
├── tsconfig.json
└── nest-cli.json
Let's briefly go over the key files:
main.ts
: The entry point of the applicationapp.module.ts
: The root module of the applicationapp.controller.ts
: A basic controller with a single routeapp.service.ts
: A basic service with a single method
Creating Your First REST API
Now that we have our project set up, let's create a simple REST API for managing a list of books. We'll implement CRUD (Create, Read, Update, Delete) operations for our book resource.
Step 1: Generate a Books Module
First, let's create a module for our books resource:
nest generate module books
This command will create a books folder in the src directory with a books.module.ts file.
Step 2: Create a Book DTO (Data Transfer Object)
Create a new file src/books/dto/create-book.dto.ts
:
export class CreateBookDto {
readonly title: string;
readonly author: string;
readonly published: number;
}
Step 3: Create a Book Service
Generate a service for handling book-related operations:
nest generate service books
Update the src/books/books.service.ts
file:
import { Injectable } from '@nestjs/common';
import { CreateBookDto } from './dto/create-book.dto';
@Injectable()
export class BooksService {
private books = [];
findAll() {
return this.books;
}
findOne(id: number) {
return this.books.find(book => book.id === id);
}
create(createBookDto: CreateBookDto) {
const book = { id: this.books.length + 1, ...createBookDto };
this.books.push(book);
return book;
}
update(id: number, updateBookDto: CreateBookDto) {
const book = this.findOne(id);
if (book) {
Object.assign(book, updateBookDto);
return book;
}
return null;
}
remove(id: number) {
const index = this.books.findIndex(book => book.id === id);
if (index !== -1) {
return this.books.splice(index, 1)[0];
}
return null;
}
}
Step 4: Create a Books Controller
Generate a controller for handling HTTP requests:
nest generate controller books
Update the src/books/books.controller.ts
file:
import { Controller, Get, Post, Body, Param, Put, Delete } from '@nestjs/common';
import { BooksService } from './books.service';
import { CreateBookDto } from './dto/create-book.dto';
@Controller('books')
export class BooksController {
constructor(private readonly booksService: BooksService) {}
@Get()
findAll() {
return this.booksService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.booksService.findOne(+id);
}
@Post()
create(@Body() createBookDto: CreateBookDto) {
return this.booksService.create(createBookDto);
}
@Put(':id')
update(@Param('id') id: string, @Body() updateBookDto: CreateBookDto) {
return this.booksService.update(+id, updateBookDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.booksService.remove(+id);
}
}
Step 5: Update the Books Module
Update the src/books/books.module.ts
file:
import { Module } from '@nestjs/common';
import { BooksController } from './books.controller';
import { BooksService } from './books.service';
@Module({
controllers: [BooksController],
providers: [BooksService],
})
export class BooksModule {}
Step 6: Update the App Module
Update the src/app.module.ts
file:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { BooksModule } from './books/books.module';
@Module({
imports: [BooksModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Testing Your API
Now that we have our REST API set up, let's test it using cURL or a tool like Postman.
- Start your NestJS application:
npm run start:dev
- Create a new book:
curl -X POST http://localhost:3000/books -H "Content-Type: application/json" -d '{"title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "published": 1925}'
- Get all books:
curl http://localhost:3000/books
- Get a specific book:
curl http://localhost:3000/books/1
- Update a book:
curl -X PUT http://localhost:3000/books/1 -H "Content-Type: application/json" -d '{"title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "published": 1926}'
- Delete a book:
curl -X DELETE http://localhost:3000/books/1
Conclusion
Congratulations! You've just created your first REST API using NestJS. We've covered the basics of setting up a NestJS project, creating modules, services, and controllers, and implementing CRUD operations for a simple resource.
This is just the beginning of what you can do with NestJS. As you continue to explore the framework, you'll discover more advanced features like:
- Middleware
- Exception filters
- Pipes for data transformation and validation
- Guards for authentication
- Interceptors for adding extra logic to incoming and outgoing responses
NestJS provides a robust set of tools for building scalable and maintainable server-side applications. Its modular architecture and use of TypeScript make it an excellent choice for developers looking to build enterprise-grade Node.js applications.
Happy coding with NestJS!