【发布时间】:2021-03-09 08:58:20
【问题描述】:
我们希望下面的查询根据返回的truckId 解析truck 字段:
实体
// RosterEntity.ts
import { Truck } from '@sap-truck-roster/entity/Truck'
import { Field, ID, ObjectType } from 'type-graphql'
@ObjectType()
export class Roster {
@Field(() => Truck, { nullable: true })
truck: Truck
@Field(() => ID)
readonly truckId: string
}
// TruckEntity.ts
import { Field, ID, ObjectType } from 'type-graphql'
@ObjectType()
export class Truck {
@Field(() => ID)
readonly id: string
@Field()
readonly description: string
}
解析器
// TruckResolver.ts
import { Resolver, Arg, Query, Ctx, Field, ObjectType, createUnionType,} from 'type-graphql'
import { Truck } from '@sap-truck-roster/entity/Truck'
import { plainToClass } from 'class-transformer'
import { Context } from '@shared/typings'
import { ApiError } from '@shared/graphql'
@ObjectType()
class TruckArray {
@Field(() => [Truck], { nullable: true })
data?: [Truck]
}
const TruckQueryResultUnion = createUnionType({
name: 'TruckQueryResult',
// types: () => [[Truck], ApiError] as const,
// an array is not supported by the Graphql spec in unions
types: () => [TruckArray, ApiError] as const,
})
@Resolver(() => Truck)
export class TruckResolver {
@Query(() => TruckQueryResultUnion)
async truck(
@Ctx() ctx: Context,
@Arg('id', { nullable: true }) id?: string,
@Arg('country', { nullable: true }) country?: string
): Promise<typeof TruckQueryResultUnion> {
const response = await ctx.dataSources.sapTruckRosterAPI.getTruck({ id, country })
return plainToClass(TruckArray, { data: response.data, })
}
}
// RosterResolver.ts
import { Resolver, Arg, Query, Ctx, Field, ObjectType, createUnionType,} from 'type-graphql'
import { Roster } from '@sap-truck-roster/entity/Roster'
import { plainToClass } from 'class-transformer'
import { Context } from '@shared/typings'
import { ApiError } from '@shared/graphql'
import { Truck } from '@sap-truck-roster/entity/Truck'
@ObjectType()
class RosterArray {
@Field(() => [Roster], { nullable: true })
data?: [Roster]
}
const RosterQueryResultUnion = createUnionType({
name: 'RosterQueryResult',
// types: () => [[Roster], ApiError] as const,
// an array is not supported by the Graphql spec in unions
types: () => [RosterArray, ApiError] as const,
})
@Resolver(() => Roster)
export class RosterResolver {
@Query(() => RosterQueryResultUnion)
async roster(
@Ctx() ctx: Context,
@Arg('date', () => String) date: string,
@Arg('truckId', { nullable: true }) truckId?: string,
@Arg('driverId', { nullable: true }) driverId?: string
): Promise<typeof RosterQueryResultUnion> {
const response = await ctx.dataSources.sapTruckRosterAPI.getRoster({ date, driverId, truckId })
// @FieldResolver(() => Truck)
// truck(@Root() truck: Truck) {
// return await ctx.dataSources.sapTruckRosterAPI.getTruck({
// id: response.truckId
// })
// }
return plainToClass(RosterArray, { data: response.data })
}
}
正如您在RosterResolver.ts 中看到的,我们尝试使用response.truckId 来查询API 上的另一个端点,但失败了。用数据填充 truck 字段的正确方法是什么?
这会在控制台中返回正确的数据,但与 roster 不匹配,因为我们获得了所有 truck 属性的 null 值:
// RosterResolver.ts
@FieldResolver(() => Truck, { nullable: true })
async truck(@Root() roster: Roster, @Ctx() ctx: Context) {
console.log('roster.truckId: ', roster.truckId)
const response = await ctx.dataSources.sapTruckRosterAPI.getTruck({
id: roster.truckId,
})
console.log('response: ', response);
return response
}
【问题讨论】:
标签: graphql apollo-server typegraphql