Providers are a fundamental building block in NestJS applications. Understanding providers will help you build more modular, maintainable, and testable applications. There are many different kinds of providers in NestJS but we're going to learn about Services. We'll be focusing on a BookService
in this lesson which is responsible for providing Book
data.
In NestJS, a Service is a class that is decorated with the @Injectable()
decorator. Services are used to encapsulate and manage business logic, data processing, and any other operations that are not directly tied to handling requests (which is the role of controllers). By separating business logic into services, you promote a clean architecture where concerns are properly separated, making your application more modular and easier to maintain.
Dependency Injection (DI) is a pattern where an object receives its dependencies from an external source rather than creating them itself. This strategy makes it easier to manage and scale your application.
In NestJS, DI is built-in and allows you to inject services and other dependencies into your classes. This is done through the use of special decorators and the NestJS DI container.
Imagine you have a coffee shop, and each coffee machine needs a supply of coffee beans. With DI, instead of each machine fetching its beans, a central service provides beans to all machines. This simplifies management and ensures each machine gets what it needs efficiently.
The BooksService
will provide methods to retrieve information about books.
import { Injectable } from '@nestjs/common';
import { Book, books } from './books.data';
// This decorator indicates that the class can be managed by the _NestJS_ **DI** system.
@Injectable()
export class BooksService {
getAllBooks(): Book[] {
return books;
}
getOneBook(id: string): Book {
return books.find((book) => book.id === id);
}
}
import { Controller, Get } from '@nestjs/common';
import { Book } from './books.data';
import { BooksService } from './books.service';
@Controller('books')
export class BooksController {
// `BooksService` is injected into the controller via the constructor
constructor(private readonly booksService: BooksService) {}
@Get()
findAll(): Book[] {
return this.booksService.getAllBooks();
}
}
To fully integrate BooksService
and BooksController
into our application, we need to declare them in a BooksModule
module.
import { Module } from '@nestjs/common';
import { BooksController } from './books.controller';
import { BooksService } from './books.service';
@Module({
controllers: [BooksController],
providers: [BooksService],
})
export class BooksModule {}