I utilized TypeORM to establish two entities: User
and School
:
@Entity()
export class User {
// ...
@ManyToOne(() => School, school => school.id)
school: School;
// ...
static from(
uid: string,
name: string,
email: string,
studentId: string,
password: string,
tel: string,
role: string,
school: School,
changePasswordToken?: string
): User {
const user = new User();
user.uid = uid;
user.name = name;
user.email = email;
user.studentId = studentId;
user.password = password;
user.tel = tel;
user.role = role;
user.school = school;
user.changePasswordToken = changePasswordToken;
return user;
}
}
@Entity()
export class School {
@PrimaryColumn()
@OneToMany(() => Product, product => product.school)
@OneToMany(() => Order, order => order.school)
@OneToMany(() => User, user => user.school)
id: string;
// ...
static from(
id: string,
name: string,
legalName: string,
address: string,
tel: string,
ceo: string,
brn: string,
mobrn: string,
password: string
): School {
const school = new School();
school.id = id;
school.name = name;
school.legalName = legalName;
school.address = address;
school.tel = tel;
school.ceo = ceo;
school.brn = brn;
school.mobrn = mobrn;
school.password = password;
return school;
}
}
User
relies on the id of the School
through a foreign key named schoolId
.
In my research on similar topics on Stack Overflow, I discovered that implementing Entity-DTO conversion in the Service layer is advisable.
As a result, I crafted the following code for SchoolsService
:
@Injectable()
export class SchoolsService {
constructor(
@InjectRepository(School) private readonly schoolRepository: Repository<School>
) { }
async findOne(id: string): Promise<ResponseSchoolDto> {
const school = await this.schoolRepository.findOne({ where: { id } });
const responseSchoolDto = plainToInstance(ResponseSchoolDto, school);
return responseSchoolDto
}
}
Now let's examine the code for UsersService
:
@Injectable
export class UsersService {
constructor(private readonly schoolsService: SchoolsService) { }
create(userData: CreateUserDto): Promise<User> {
const user = instanceToPlain(userData);
// WHAT SHOULD I DO?
// const responseSchoolDto = this.schoolsService.findOne(userData.schoolId);
// const school = plainToInstance(School, responseSchoolDto);
return this.userRepository.save(user);
}
}
As stated earlier, the DTO needs to be converted to Entity in order to provide a schoolId
to the User Entity since the Service is designed to return DTOs.
Nevertheless, I believe that the approach I employed is not suitable as UsersService
relies on SchoolsService
, School
(Entity), and DTO. After much contemplation, the only resolution seems to be for the Service to return Entity.
During my quest for a solution to this dilemma, I encountered someone who implemented the practice of converting DTO to Entity within the DTO itself. However, I am hesitant to endorse this method as I believe DTOs should only contain pure data. Is there a more efficient structure to tackle this issue?