Imagine having two different entities:
// user.entity.ts
@ObjectType()
@Entity()
export class User {
@Field()
@PrimaryGeneratedColumn('uuid')
id: string;
@Field()
@Column({ unique: true })
username: string;
@Column({ select: false })
password: string;
@Field(() => [Task])
@OneToMany(() => Task, (task) => task.author)
authorOfTasks: Task[]
}
and
// task.entity.ts
@ObjectType()
@Entity()
export class Task {
@Field()
@PrimaryGeneratedColumn('uuid')
id: string;
@Field()
@Column()
title: string;
@Field()
@Column({ nullable: true })
description?: string;
@Field(() => User)
@ManyToOne(() => User, (user) => user.authorOfTasks)
author: User;
}
In order to resolve the authorOfTasks
field in UserResolver
and the author
field in TaskResolver
, you need to inject UserService
and TaskService
in both resolvers. This can be achieved by:
// user.resolver.ts
@Resolver(of => User)
export class UserResolver {
constructor(
private userService: UserService,
private taskService: TaskService
) {}
// Some queries using userService
@ResolveField(() => [Task])
async authorOfTasks(
@Parent() author: User
) {
return this.taskService.getTasksByAuthor(author)
}
}
and
// task.resolver.ts
@Resolver()
export class TaskResolver {
constructor(
private taskService: TaskService,
private userService: UserService
) {}
// Some queries using taskService
@ResolveField(() => User)
async author(
@Parent() task: Task
) {
return this.userService.getUserById(task.author.id)
}
}
Injecting TaskService
and UserService
in both resolvers can lead to circular dependencies in your Nest application. Although you can use forwardRef
to handle this, it is recommended to avoid circular dependencies whenever possible according to Nest documentation.
What can be done in this scenario? Should the app be restructured somehow to keep the code modular? The current structure is as shown below:
https://i.sstatic.net/sTLLM.png
Thank you! 🙏