如何解决 graphql 突变的嵌套输入类型

How to resolve nested input types on graphql mutation

所以我在尝试解决包含来自另一个输入类型的嵌套输入类型的突变时遇到问题,如果我对模型进行了错误的设计,请纠正我。

这就是突变,我正在使用 Playground 查看它:

mutation{
  createOrganization(
    name: "Bitas"
    staff: [
      {
        firstName: "Albert"
        lastName: "Chavez"
        position: "Developer"
        contactInformation:[
            {
                email: "hola@mail.com"
                phone:"9187631"
                linkedin: "whatever"
            },
            {
                email: "hola2@mail.com"
                phone:"91876312"
                linkedin: "whatever2"
            }
          ]
        }
    ]
  ){
    name
    staff{
      firstName
      contactInformation{
        email
      }
    }
  }
}

此突变在组织和员工之间创建关系,同时在员工和联系信息之间创建关系...这里是模式:

type Organization {
    id: ID!
    name: String!
    staff: [Employee!]!
}

type Employee {
    id: ID!
    firstName: String!
    lastName: String!
    position: String!
    contactInformation: [ContactInfo!]!
    belongsToOrg: Organization
}

input employeeInput {
    firstName: String!
    lastName: String!
    position: String!
    contactInformation: [contactInfoInput!]!
    belongsToOrg: ID
}

type ContactInfo {
    id: ID!
    email: String!
    phone: String!
    linkedin: String!
    belongsTo: Employee!
}

input contactInfoInput {
    email: String!
    phone: String!
    linkedin: String!
}

如果我没有正确创建突变,请纠正我

type Mutation {
    createOrganization(name: String!, staff: [employeeInput!]): Organization!
    createEmployee(firstName: String!, lastName: String!, position:String!, contactInformation: [contactInfoInput!]!): Employee!
}

下面是要创建的函数:

function createEmployee(parent, args, context, info) {
    return context.prisma.createEmployee({
        firstName: args.firstName,
        lastName: args.lastName,
        position: args.position,
        contactInformation: {
            create: args.contactInformation
        },
    })
}

function createOrganization(parent, args, context, info) {
    return context.prisma.createOrganization({
        name: args.name,
        staff: {
            create: args.staff
        }
    })
}

function staff(parent, args, context) {
    return context.prisma.organization({id: parent.id}).staff();
}

function contactInformation(parent, args, context) {
    return context.prisma.employee({id: parent.id}).contactInformation()
}

function belongsTo(parent, args, context) {
    return context.prisma.contactInfo({id: parent.id}).belongsTo()
}

所以当我在 Playground 上点击 mutation 时,它给了我错误:

原因:'staff.create[0].contactInformation' 预期 'ContactInfoCreateManyWithoutEmployeeInput',未找到对象。

有人可以解释一下这是什么意思吗??我没有正确设计架构或关系吗?或者也许是因为嵌套输入的级别太多?? 如果我 console.log createOrganization 函数中的 contactInformation 字段值未定义。

注意:创建 Employee 时,嵌套突变工作正常。

提前致谢。

问题出在传递给 prisma 绑定函数的输入中。

让我们从 createOrganization 突变开始。这就是 createOrganization 突变的字段定义的样子 - createOrganization(name: String!, staff: [employeeInput!]): Organization! 其中 staff 是类型 employeeInput 的关系字段,如下所示:

input employeeInput {
    firstName: String!
    lastName: String!
    position: String!
    contactInformation: [contactInfoInput!]!
    belongsToOrg: ID
}

请注意,此处的 ContactInformation 字段是 contactInfoInput 的数组,如下所示:

type ContactInfo {
    id: ID!
    email: String!
    phone: String!
    linkedin: String!
    belongsTo: Employee!
}

如果我们查看 Prisma 生成的模式,您会注意到对于每个关系字段,我们都有嵌套的突变字段 - createconnectupdateupsert 等等,当我们调用 prisma 绑定时,我们需要遵守 Prisma 的模式。

现在,如果我们看一下解析器,

function createOrganization(parent, args, context, info) {
    return context.prisma.createOrganization({
        name: args.name,
        staff: {
            create: args.staff
        }
    })
}

args.staff 在此处作为 create 输入正确传递,但问题出在 args.staff 中的 contactInformation 数组中。它的值与 Prisma 架构中定义的 ContactInfoCreateManyWithoutEmployeeInput 类型不匹配。将上面的解析器更改为以下将为您解决问题,但我建议更好地设计突变的输入类型:

function createOrganization(parent, args, context, info) {
    const { staff } = args
    return context.prisma.createOrganization({
        name: args.name,
        staff: {
            create: staff.map((emp) => ({
               firstName: emp.firstName,
               lastName: emp.lastName,
               position: emp.position,
               contactInformation: {
                   create: emp.contactInformation || []
               }
            }))
        }
    })
}