Detailed Explanation of the Main Files and Directories in the src
Directory of a NestJS Project
- 815Words
- 4Minutes
- 07 Jul, 2024
The directory structure of a NestJS project is clear and highly scalable. Understanding and properly using the roles of various files and directories in a project is crucial for building efficient and maintainable projects. This article will provide a detailed explanation of the main files and directories in the src
directory of a NestJS project and demonstrate how multiple modules collaborate through practical examples.
app.module.ts
The app.module.ts
file is the root module of a NestJS application. It defines the main structure and dependencies of the application. All modules, controllers, and services are registered and managed through the root module.
1import { Module } from "@nestjs/common";2import { TypeOrmModule } from "@nestjs/typeorm";3import { ConfigModule } from "@nestjs/config";4import { UsersModule } from "./users/users.module";5import { ProductsModule } from "./products/products.module";6
7@Module({8 imports: [9 ConfigModule.forRoot(),10 TypeOrmModule.forRoot(),11 UsersModule,12 ProductsModule,13 ],14 controllers: [],15 providers: [],16})17export class AppModule {}
In the example above, AppModule
imports UsersModule
and ProductsModule
, making them part of the application.
main.ts
The main.ts
file is the entry point of a NestJS application. It is responsible for bootstrapping the application and starting the NestJS HTTP server.
1import { NestFactory } from "@nestjs/core";2import { AppModule } from "./app.module";3
4async function bootstrap() {5 const app = await NestFactory.create(AppModule);6 await app.listen(3000);7}8bootstrap();
In the example above, the main.ts
file uses NestFactory
to create a NestJS application based on AppModule
and listens on port 3000
.
controllers
Controllers in NestJS are classes used to handle HTTP requests. Each controller defines a set of routes that correspond to different request paths and methods.
1import { Controller, Get, Post, Body, Param } from "@nestjs/common";2import { UsersService } from "./users.service";3import { CreateUserDto } from "./dto/create-user.dto";4
5@Controller("users")6export class UsersController {7 constructor(private readonly usersService: UsersService) {}8
9 @Get()10 findAll() {11 return this.usersService.findAll();12 }13
14 @Get(":id")15 findOne(@Param("id") id: string) {16 return this.usersService.findOne(+id);17 }18
19 @Post()20 create(@Body() createUserDto: CreateUserDto) {21 return this.usersService.create(createUserDto);22 }23}
In the example above, UsersController
defines three routes handling the /users
path: GET /users
, GET /users/:id
, and POST /users
.
services
Services in NestJS are classes used to handle business logic. Services are typically injected into controllers to process requests and return data.
1import { Injectable } from "@nestjs/common";2import { User } from "./user.entity";3import { InjectRepository } from "@nestjs/typeorm";4import { Repository } from "typeorm";5import { CreateUserDto } from "./dto/create-user.dto";6
7@Injectable()8export class UsersService {9 constructor(10 @InjectRepository(User)11 private usersRepository: Repository<User>,12 ) {}13
14 findAll(): Promise<User[]> {15 return this.usersRepository.find();16 }17
18 findOne(id: number): Promise<User> {19 return this.usersRepository.findOneBy({ id });20 }21
22 create(createUserDto: CreateUserDto): Promise<User> {23 const user = this.usersRepository.create(createUserDto);24 return this.usersRepository.save(user);25 }26}
In the example above, UsersService
uses TypeORM
to handle CRUD operations for the User
entity and provides findAll
, findOne
, and create
methods.
modules
Modules in NestJS are classes used to organize the application structure. Each module can contain multiple controllers and services and can import other modules.
1import { Module } from "@nestjs/common";2import { TypeOrmModule } from "@nestjs/typeorm";3import { UsersController } from "./users.controller";4import { UsersService } from "./users.service";5import { User } from "./user.entity";6
7@Module({8 imports: [TypeOrmModule.forFeature([User])],9 controllers: [UsersController],10 providers: [UsersService],11})12export class UsersModule {}
In the example above, UsersModule
imports TypeOrmModule
and registers the User
entity, while also defining UsersController
and UsersService
.
Collaboration Between Multiple Modules
In practical projects, multiple modules need to collaborate. Below, we use UsersModule
and ProductsModule
as an example to demonstrate how to use a service from one module in another module.
First, create a ProductsModule
:
1nest generate module products2nest generate controller products3nest generate service products
Define the Product
entity:
1import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";2
3@Entity()4export class Product {5 @PrimaryGeneratedColumn()6 id: number;7
8 @Column()9 name: string;10
11 @Column()12 price: number;13}
Configure ProductsModule
:
1import { Module } from "@nestjs/common";2import { TypeOrmModule } from "@nestjs/typeorm";3import { ProductsController } from "./products.controller";4import { ProductsService } from "./products.service";5import { Product } from "./product.entity";6import { UsersModule } from "../users/users.module"; // Import UsersModule7
8@Module({9 imports: [TypeOrmModule.forFeature([Product]), UsersModule], // Import UsersModule10 controllers: [ProductsController],11 providers: [ProductsService],12})13export class ProductsModule {}
Use UsersService
in ProductsService
:
1import { Injectable } from "@nestjs/common";2import { InjectRepository } from "@nestjs/typeorm";3import { Repository } from "typeorm";4import { Product } from "./product.entity";5import { UsersService } from "../users/users.service"; // Import UsersService6
7@Injectable()8export class ProductsService {9 constructor(10 @InjectRepository(Product)11 private productsRepository: Repository<Product>,12 private usersService: UsersService, // Inject UsersService13 ) {}14
15 findAll(): Promise<Product[]> {16 return this.productsRepository.find();17 }18
19 findOne(id: number): Promise<Product> {20 return this.productsRepository.findOneBy({ id });21 }22
23 async create(name: string, price: number): Promise<Product> {24 const user = await this.usersService.findOne(1); // Use UsersService25 if (user) {26 const product = this.productsRepository.create({ name, price });27 return this.productsRepository.save(product);28 }29 return null;30 }31}
In the example above, ProductsService
injects UsersService
through the constructor and uses its methods in the create
method.
Conclusion
This article provides a detailed explanation of the main files and directories in the src
directory of a NestJS project, including app.module.ts
, main.ts
, controllers, services, and modules, and demonstrates how multiple modules collaborate through practical examples. By organizing and using these files and directories properly, you can build efficient and maintainable NestJS projects.