I have a FinalClass that extends a BasicClass, with 2 additional fields of 2 other Classes. Basic Class and the 2 other Classes are linked to typeOrm Entites and a foreignkey in each class enabled to join the data.
I want the final class to gather all data so that I can query all of them. But I don't know how to implement the resolver in a proper way, for example, a getAllFinal() which will go through all BasicClass reports and collect the 2 other data.
I tried to create a resolver getAllBasic() in BasicClass, FieldResolvers for each additional fields in the FinalClass ? But I'm wondering , how I call all that stuff in the getAllFinal() ?
@ObjectType()
export class FinalClass extends BasicClass{
@Field(() => [AnotherClass2], { nullable: true })
userAliases: AnotherClass2[];
@Field(() => [AnotherClass3], { nullable: true })
userIdentity: AnotherClass3[];
}
@ObjectType()
export class BasicClass {
@Field(()=>ID!)
bcPrimaryKey: string;
}
@ObjectType()
export class AnotherClass2 {
@Field()
ac2PrimaryKey: string;
@Field()
bcPrimaryKey : string;
@Field()
value : number
}
@ObjectType()
export class AnotherClass3 {
@Field()
ac3PrimaryKey: string;
@Field()
bcPrimaryKey : string;
@Field()
thevalue : number
@Field()
thevalue2 : boolean
}
the below resolver is working fine, but this is not a clean way to do it I guess, because I'm calling the DB for each field:
@Resolver(FinalClass )
export class FinalClassResolver {
@Query(() => [FinalClass ], { nullable: true })
async getAllFinal(
@Ctx() context: GlobalContext
): Promise<Array<Promise<FinalClass >>> {
const features: BasicClass[] = await context.dbConnection
.getRepository<BasicClass>("BasicClass")
.createQueryBuilder("features")
.skip(0)
.take(1000)
.getMany();
const resu = features.map(async (user: BasicClass) => {
const aliases: AnotherClass2[] = await context.dbConnection
.getRepository<AnotherClass2 >("AnotherClass2 ")
.createQueryBuilder("alias")
.where("alias.bcPrimaryKey=:email", { email: user.bcPrimaryKey })
.getMany();
const identity: AnotherClass3[] = await context.dbConnection
.getRepository<AnotherClass3>("AnotherClass3")
.createQueryBuilder("identity")
.where("identity.bcPrimarykey=:email", { email: user.bcPrimaryKey})
.getMany();
const item: BasicClass= {
...user,
userAliases: aliases,
userIdentity: identity
};
return item;
});
return resu;
}
getAllFinal
query should just return the list of base fields of FinalClass
. Then you should create field resolvers userAliases
and userIdentity
of FinalClass
that will resolve the relation between FinalClass
and AnotherClass2
/ AnotherClass3
.
That's the architecture of GraphQL resolvers. It's not super-optimal (3 queries) but with a dataloader it's much more optimized than REST when client perform 20 HTTP calls.
Finally came up with a cleaner way by creating a resolver in BaseClass, extending it in the FinalClassResolver and adding the missing fieldResolvers in the FinalClassResolver
@Resolver(BasicClass)
export class BasicClassResolver {
@Query(() => [BasicClass], { nullable: true })
async getBasicClassItems(
@Ctx() context: GlobalContext
): Promise<BasicClass[]> {
const items: BasicClass[] = await context.dbConnection
.getRepository<BasicClass>("BasicClass")
.createQueryBuilder("items")
.skip(0)
.limit(1000)
.getMany();
return items;
}
}
@Resolver(FinalClass)
export class FinalClassResolver extends BasicClassResolver {
@Query(() => [FinalClass], { nullable: true })
async getAllFinalItems (@Ctx() context: GlobalContext) {
return this.getBasicClassItems(context);
}
@FieldResolver()
async userAliases(
@Root() item: BasicClass,
@Ctx() context: GlobalContext
): Promise<AnotherClass2[]> {
const aliases: AnotherClass2[] = await context.dbConnection
.getRepository<AnotherClass2>("AnotherClass2")
.createQueryBuilder("alias")
.where("alias.itemId=:itemId", { itemId: item.Id })
.getMany();
return aliases;
}
@FieldResolver()
async userIdentity(
@Root() item: BasicClass,
@Ctx() context: GlobalContext
): Promise<AnotherClass3[]> {
const identity: AnotherClass3[] = await context.dbConnection
.getRepository<AnotherClass3>("AnotherClass3")
.createQueryBuilder("identity")
.where("identity.itemId=:itemId", { itemId: item.id})
.getMany();
return identity;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.