TypeGraphQL - 无法匹配联合的所有接口
TypeGraphQL - Not able to match all the interfaces of a union
总结
目标是使用联合声明 return 类型的突变,以表达多种状态:成功和用户错误
能够根据用例select具体类型:
mutation($data: CreateUserInput!) {
createUser(data: $data){
... on CreateUserSuccess {
user {
id
}
}
... on EmailTakenError {
emailWasTaken
}
... on UserError {
code
message
}
}
}
使用 TypeGraphQ 实现:
@ObjectType()
class CreateUserSuccess {
@Field(() => User)
user: User
}
@ObjectType()
class EmailTakenError {
@Field()
emailWasTaken: boolean
}
const mapMutationValueKeyToObjectType = {
user: CreateUserSuccess,
code: UserError,
emailWasTaken: EmailTakenError
}
const CreateUserPayload = createUnionType({
name: 'CreateUserPayload',
types: () => [CreateUserSuccess, EmailTakenError, UserError] as const,
resolveType: mutationValue => {
const mapperKeys = Object.keys(mapMutationValueKeyToObjectType)
const mutationValueKey = mapperKeys.find((key) => key in mutationValue)
return mapMutationValueKeyToObjectType[mutationValueKey]
}
})
@InputType()
class CreateUserInput implements Partial<User> {
@Field()
name: string
@Field()
email: string
}
@Resolver(User)
export class UserResolver {
@Mutation(() => CreateUserPayload)
createUser (@Arg('data', {
description: 'Represents the input data needed to create a new user'
}) createUserInput: CreateUserInput) {
const { name, email } = createUserInput
return createUser({ name, email })
}
}
数据层
export const createUser = async ({
name, email
}: { name: string; email: string; }) => {
const existingUser = await dbClient.user.findUnique({
where: {
email
}
})
if (existingUser) {
return {
code: ErrorCode.DUPLICATE_ENTRY,
message: "There's an existing user with the provided email.",
emailWasTaken: true
}
}
return dbClient.user.create({
data: {
name,
email
}
})
}
问题
响应不会根据联合解析所有 selected 字段,即使 returning 与不同类型相关的字段也是如此
if (existingUser) {
return {
code: ErrorCode.DUPLICATE_ENTRY,
message: "There's an existing user with the provided email.",
emailWasTaken: true
}
}
我怀疑这种情况是,如果 EmailTakenError
类型正在 selected,为什么 emailWasTaken
没有在响应中被 returned?
这是我的解释错误
原因是 return 定义为联合类型的解析器确实应该 return 其中之一,在上述情况下,UserError
和 EmailTakenError
不会return接受相同的回复
总结
目标是使用联合声明 return 类型的突变,以表达多种状态:成功和用户错误
能够根据用例select具体类型:
mutation($data: CreateUserInput!) {
createUser(data: $data){
... on CreateUserSuccess {
user {
id
}
}
... on EmailTakenError {
emailWasTaken
}
... on UserError {
code
message
}
}
}
使用 TypeGraphQ 实现:
@ObjectType()
class CreateUserSuccess {
@Field(() => User)
user: User
}
@ObjectType()
class EmailTakenError {
@Field()
emailWasTaken: boolean
}
const mapMutationValueKeyToObjectType = {
user: CreateUserSuccess,
code: UserError,
emailWasTaken: EmailTakenError
}
const CreateUserPayload = createUnionType({
name: 'CreateUserPayload',
types: () => [CreateUserSuccess, EmailTakenError, UserError] as const,
resolveType: mutationValue => {
const mapperKeys = Object.keys(mapMutationValueKeyToObjectType)
const mutationValueKey = mapperKeys.find((key) => key in mutationValue)
return mapMutationValueKeyToObjectType[mutationValueKey]
}
})
@InputType()
class CreateUserInput implements Partial<User> {
@Field()
name: string
@Field()
email: string
}
@Resolver(User)
export class UserResolver {
@Mutation(() => CreateUserPayload)
createUser (@Arg('data', {
description: 'Represents the input data needed to create a new user'
}) createUserInput: CreateUserInput) {
const { name, email } = createUserInput
return createUser({ name, email })
}
}
数据层
export const createUser = async ({
name, email
}: { name: string; email: string; }) => {
const existingUser = await dbClient.user.findUnique({
where: {
email
}
})
if (existingUser) {
return {
code: ErrorCode.DUPLICATE_ENTRY,
message: "There's an existing user with the provided email.",
emailWasTaken: true
}
}
return dbClient.user.create({
data: {
name,
email
}
})
}
问题
响应不会根据联合解析所有 selected 字段,即使 returning 与不同类型相关的字段也是如此
if (existingUser) {
return {
code: ErrorCode.DUPLICATE_ENTRY,
message: "There's an existing user with the provided email.",
emailWasTaken: true
}
}
我怀疑这种情况是,如果 EmailTakenError
类型正在 selected,为什么 emailWasTaken
没有在响应中被 returned?
这是我的解释错误
原因是 return 定义为联合类型的解析器确实应该 return 其中之一,在上述情况下,UserError
和 EmailTakenError
不会return接受相同的回复