【问题标题】:How to resolve nested input types on graphql mutation如何解决 graphql 突变上的嵌套输入类型
【发布时间】:2019-08-15 09:11:30
【问题描述】:

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

这是突变,我正在使用 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 上遇到突变时,它给了我错误:

原因:“staff.create[0].contactInformation”应为“ContactInfoCreateManyWithoutEmployeeInput”,找不到对象。

请有人解释一下这是什么意思?我没有正确设计架构或关系吗?或者可能是因为嵌套输入的级别太多? 如果我控制台记录 createOrganization 函数上的 contactInformation 字段,则该值未定义。

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

提前致谢。

【问题讨论】:

    标签: javascript graphql prisma


    【解决方案1】:

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

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

    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 || []
                   }
                }))
            }
        })
    }
    
    

    【讨论】:

    • 显然此解决方案不起作用...我收到此错误:原因:'staff.create[0].firstName' Expected non-null value, found null.
    • 所以我想我需要迭代传递的人员数组......然后迭代联系人信息数组..这是正确的吗?如果是这样,为什么员工变异不需要迭代??
    • 我更新了代码以遍历 staff 数组,我之前错过了。在createEmployee 突变的情况下,您在contactInfo 中只有一个名为belongsTo 的关系字段,我猜它没有在输入中传递,这就是突变起作用的原因,因为您已经有create 用于contactInfo。在输入中设置belongsTo 时,事情会中断。
    猜你喜欢
    • 2020-12-09
    • 2020-05-13
    • 2019-08-24
    • 2016-02-07
    • 2020-01-31
    • 2017-12-18
    • 2020-04-24
    • 2018-08-24
    • 2021-04-09
    相关资源
    最近更新 更多