Dependency Injection (DI) in NestJS simplifies the process of managing dependencies between services and classes. Let’s explore it using a BookService example to demonstrate how DI works in NestJS. 🚀
🎯 Scenario
We want to build an application that:
- Retrieves a list of books from a database. 📖
- Formats the books for display. ✨
We’ll use the following services:
- BookService: Handles book-related logic. 🛠️
- DatabaseService: Handles database interactions. 💾
🛠️ Step 1: Creating the DatabaseService
The DatabaseService simulates retrieving data from a database.
import { Injectable } from '@nestjs/common';
@Injectable()
export class DatabaseService {
private books = [
{ id: 1, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
{ id: 2, title: '1984', author: 'George Orwell' },
{ id: 3, title: 'To Kill a Mockingbird', author: 'Harper Lee' },
];
getAllBooks() {
return this.books;
}
}
🛠️ Step 2: Creating the BookService
The BookService depends on the DatabaseService to retrieve books and then formats the output.
import { Injectable } from '@nestjs/common';
import { DatabaseService } from './database.service';
@Injectable()
export class BookService {
constructor(private readonly databaseService: DatabaseService) {}
getFormattedBooks() {
const books = this.databaseService.getAllBooks();
return books.map((book) => `${book.title} by ${book.author}`);
}
}
Here, the DatabaseService is injected into the BookService through the constructor. 🔗
📦 Step 3: Registering Services in a Module
Both services need to be registered as providers in a module. 🗂️
import { Module } from '@nestjs/common';
import { BookService } from './book.service';
import { DatabaseService } from './database.service';
@Module({
providers: [BookService, DatabaseService],
exports: [BookService], // Exporting BookService for use in other modules
})
export class BookModule {}
🌐 Step 4: Using the BookService in a Controller
We can now use the BookService in a controller to expose the functionality through an API.
import { Controller, Get } from '@nestjs/common';
import { BookService } from './book.service';
@Controller('books')
export class BookController {
constructor(private readonly bookService: BookService) {}
@Get()
getBooks() {
return this.bookService.getFormattedBooks();
}
}
📦 Step 5: Adding the Controller to the Module
Update the BookModule to include the controller. 📑
import { Module } from '@nestjs/common';
import { BookService } from './book.service';
import { DatabaseService } from './database.service';
import { BookController } from './book.controller';
@Module({
providers: [BookService, DatabaseService],
controllers: [BookController],
})
export class BookModule {}
🛠️ How Dependency Injection Works Here
-
DatabaseService:
- Declared as a provider using the
@Injectable()decorator. 🛠️ - Registered in the module. ✅
- Injected into the
BookService. 🔗
- Declared as a provider using the
-
BookService:
- Declared as a provider using the
@Injectable()decorator. 🛠️ - Injected into the
BookController. 🔗
- Declared as a provider using the
-
IoC Container:
- NestJS automatically resolves and injects the dependencies (
DatabaseService→BookService→BookController). 🤖
- NestJS automatically resolves and injects the dependencies (
✨ Example Output
When you make a GET request to /books, the response would look like:
[
"The Great Gatsby by F. Scott Fitzgerald",
"1984 by George Orwell",
"To Kill a Mockingbird by Harper Lee"
]
🎉 Advantages of DI in NestJS
-
Loose Coupling:
BookServicedoesn’t need to know howDatabaseServiceworks. 🔗 -
Reusability: Services like
DatabaseServicecan be reused across the app. ♻️ - Testing: Mock services can be injected during testing for isolated unit tests. 🧪
🚀 Summary
Dependency Injection in NestJS automates the creation and wiring of dependencies. By using decorators like @Injectable(), @Module(), and constructor injection, we can build scalable and maintainable applications. 🛠️
With this approach, we’ve created a clean and reusable architecture for the BookService example, demonstrating the power and simplicity of DI in NestJS. 📚✨
Top comments (0)