In NestJS, Modules help structure the application, making it organized, scalable, and maintainable.
Dependency Injection (DI) is a design pattern used to implement IoC (Inversion of Control), allowing dependencies to be injected into a class rather than the class creating them itself. This improves code modularity and ease of testing.
In NestJS, DI is implemented through the use of decorators like @Injectable() and types that indicate what should be injected. Modules in NestJS group related components, like services and controllers, together. This modular approach keeps your code organized and helps manage dependencies effectively.
@Module() decorator which takes metadata objectimport { Module } from '@nestjs/common';
import { BooksController } from './books.controller';
import { BooksService } from './books.service';
@Module({
controllers: [BooksController],
providers: [BooksService],
})
export class BooksModule {}import { Injectable } from '@nestjs/common';
const ratings = {
'6abc1421-843f-4eb2-8693-5c1a319f1976': 4,
'ac4ab8e0-29d6-4b47-bf6e-6737e1e8115b': 5,
'cb4fce20-c17e-4ebb-ae27-cb04af5b530f': 3,
};
@Injectable()
export class BookRatingsService {
getRatingForBook(id: string): number {
return ratings[id] ?? 0;
}
}import { Injectable } from '@nestjs/common';
import { BookRatingsService } from './bookRatings.service';
import { Book, books } from './books.data';
@Injectable()
export class BooksService {
constructor(private readonly bookRatingsService: BookRatingsService) {}
getAllBooks(): Book[] {
return books.map((book) => ({
...book,
rating: this.bookRatingsService.getRatingForBook(book.id),
}))
}
}By registering both BooksService and BookRatingsService in the BooksModule, you can group related services that handle book-related logic together.
Modules defined in this way can be reused in different parts of a NestJS application. For example, if you later need to build an AuthorsModule, it could follow the same structure, allowing you to build a highly modular and maintainable system.
import { Module } from '@nestjs/common';
import { BooksController } from './books.controller';
import { BooksService } from './books.service';
import { BookRatingsService } from './bookRatings.service';
@Module({
controllers: [BooksController],
providers: [
BooksService,
BookRatingsService,
]
})
export class BooksModule {}By integrating the BooksModule into the main AppModule, the BooksModule is now a part of the overall application.
AppModule continues to serve its initial purposeBooksModule so both sets of routes are exposedBooksController will be accessible alongside any other routes defined in the AppController or any other modules that might be added in the futureimport { 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 {}