Проблема NestJS с циклической зависимостью и неопределенным импортом
Последние несколько дней я изучал NestJS + Graphql + Mongoose, создавая небольшой проект, но начал находить некоторые проблемы из-за отношений с базой данных и циклической зависимости. На данный момент я могу запросить у пациента список предыдущих госпитализаций (сначала код)
type Patient {
_id: ID!
name: String!
hospitalizations: [Hospitalization!]!
}
type Hospitalization {
_id: ID!
hospitalBed: Bed!
patient: Patient!
}
type PaginatedHospitalization {
totalCount: Int!
edges: [HospitalizationEdge!]
pageInfo: PageInfo!
}
type HospitalizationEdge {
cursor: String!
node: Hospitalization!
}
но я не могу обновить, чтобы обновитьhospitalizations
бытьPaginatedHospitalization
вероятно, из-за какой-то проблемы с циклической зависимостью, о которой я не знаю. Ошибка, которую я получаю на терминале при попытке запустить проект:
[8:35:19 AM] Starting compilation in watch mode...
[8:35:21 AM] Found 0 errors. Watching for file changes.
================ Hospitalization undefined
==== classRef undefined
/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/common/entities/paginated.entity.ts:18
@ObjectType(`${classRef.name}Edge`)
^
TypeError: Cannot read properties of undefined (reading 'name')
at Paginated (/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/common/entities/paginated.entity.ts:18:27)
at Object.<anonymous> (/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/hospitalization/entities/paginated-hospitalization.entity.ts:9:56)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/patient/entities/patient.entity.ts:7:1)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
это мои модули
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017/nest-mongo'),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
BedModule,
HospitalizationModule,
PatientModule,
],
})
export class AppModule {}
@Module({
imports: [
MongooseModule.forFeature([{ name: Patient.name, schema: PatientSchema }]),
forwardRef(() => HospitalizationModule),
],
providers: [PatientResolver, PatientService],
exports: [PatientService],
})
export class PatientModule {}
@Module({
imports: [
MongooseModule.forFeature([{ name: Bed.name, schema: BedSchema }]),
forwardRef(() => HospitalizationModule),
],
providers: [BedResolver, BedService],
exports: [BedService],
})
export class BedModule {}
@Module({
imports: [
MongooseModule.forFeature([
{ name: Hospitalization.name, schema: HospitalizationSchema },
]),
forwardRef(() => BedModule),
forwardRef(() => PatientModule),
],
providers: [HospitalizationResolver, HospitalizationService],
exports: [HospitalizationService],
})
export class HospitalizationModule {}
Это мои Сущности
@Schema()
@ObjectType()
export class Patient extends BaseEntity {
@Prop({ required: true })
@Field()
name: string;
@Prop({
type: [{ type: MongoSchema.Types.ObjectId, ref: 'Hospitalization' }],
})
// @Field(() => [Hospitalization], { defaultValue: [] })
@Field(() => PaginatedHospitalization)
hospitalizations?: Hospitalization[];
}
@Schema()
@ObjectType()
export class Bed extends BaseEntity {
@Prop({ required: true })
@Field()
name: string;
@Prop({
type: [{ type: MongoSchema.Types.ObjectId, ref: 'Hospitalization' }],
})
@Field(() => [Hospitalization], { defaultValue: [] })
// TODO: will be update to PaginatedHospitalization as well
hospitalizations?: Hospitalization[];
}
@Schema()
@ObjectType()
export class Hospitalization extends BaseEntity {
@Prop({ type: MongoSchema.Types.ObjectId, ref: 'Bed' })
@Field(() => Bed)
hospitalBed?: Bed;
@Prop({ type: MongoSchema.Types.ObjectId, ref: 'Patient' })
@Field(() => Patient)
patient?: Patient;
}
Мой объект с разбивкой на страницы основан на этом общем объекте разбиения на страницы из документации NestJS.
export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
console.log('==== classRef', classRef);
@ObjectType(`${classRef.name}Edge`)
abstract class EdgeType {
@Field(() => String)
cursor: string;
@Field(() => classRef)
node: T;
}
@ObjectType({ isAbstract: true })
abstract class PaginatedType implements IPaginatedType<T> {
@Field(() => Int)
totalCount: number;
@Field(() => [EdgeType], { nullable: true })
edges: EdgeType[];
@Field(() => PageInfo)
pageInfo: PageInfo;
}
return PaginatedType as Type<IPaginatedType<T>>;
}
console.log('================ Hospitalization', Hospitalization);
@ObjectType()
export class PaginatedHospitalization extends Paginated(Hospitalization) {}
В документах и примерах я видел несколько случаев отдельных модулей, таких как PetModule, OwnerModule, но в документах говорится, что циклической зависимости следует избегать, где это возможно. Это тот случай, когда у меня должен быть один модуль с пациентом, койкой и госпитализацией в одном модуле или какое-то другое решение?