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 productsDefine 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.