260223:1415 20260223 nextJS & nestJS Best pratices
All checks were successful
Build and Deploy / deploy (push) Successful in 4m44s
All checks were successful
Build and Deploy / deploy (push) Successful in 4m44s
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: Avoid Circular Dependencies
|
||||
impact: CRITICAL
|
||||
impactDescription: "#1 cause of runtime crashes"
|
||||
tags: architecture, modules, dependencies
|
||||
---
|
||||
|
||||
## Avoid Circular Dependencies
|
||||
|
||||
Circular dependencies occur when Module A imports Module B, and Module B imports Module A (directly or transitively). NestJS can sometimes resolve these through forward references, but they indicate architectural problems and should be avoided. This is the #1 cause of runtime crashes in NestJS applications.
|
||||
|
||||
**Incorrect (circular module imports):**
|
||||
|
||||
```typescript
|
||||
// users.module.ts
|
||||
@Module({
|
||||
imports: [OrdersModule], // Orders needs Users, Users needs Orders = circular
|
||||
providers: [UsersService],
|
||||
exports: [UsersService],
|
||||
})
|
||||
export class UsersModule {}
|
||||
|
||||
// orders.module.ts
|
||||
@Module({
|
||||
imports: [UsersModule], // Circular dependency!
|
||||
providers: [OrdersService],
|
||||
exports: [OrdersService],
|
||||
})
|
||||
export class OrdersModule {}
|
||||
```
|
||||
|
||||
**Correct (extract shared logic or use events):**
|
||||
|
||||
```typescript
|
||||
// Option 1: Extract shared logic to a third module
|
||||
// shared.module.ts
|
||||
@Module({
|
||||
providers: [SharedService],
|
||||
exports: [SharedService],
|
||||
})
|
||||
export class SharedModule {}
|
||||
|
||||
// users.module.ts
|
||||
@Module({
|
||||
imports: [SharedModule],
|
||||
providers: [UsersService],
|
||||
})
|
||||
export class UsersModule {}
|
||||
|
||||
// orders.module.ts
|
||||
@Module({
|
||||
imports: [SharedModule],
|
||||
providers: [OrdersService],
|
||||
})
|
||||
export class OrdersModule {}
|
||||
|
||||
// Option 2: Use events for decoupled communication
|
||||
// users.service.ts
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
constructor(private eventEmitter: EventEmitter2) {}
|
||||
|
||||
async createUser(data: CreateUserDto) {
|
||||
const user = await this.userRepo.save(data);
|
||||
this.eventEmitter.emit('user.created', user);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
// orders.service.ts
|
||||
@Injectable()
|
||||
export class OrdersService {
|
||||
@OnEvent('user.created')
|
||||
handleUserCreated(user: User) {
|
||||
// React to user creation without direct dependency
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reference: [NestJS Circular Dependency](https://docs.nestjs.com/fundamentals/circular-dependency)
|
||||
Reference in New Issue
Block a user