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:
BookService
doesnβt need to know howDatabaseService
works. π -
Reusability: Services like
DatabaseService
can 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)