嵌套对象数组的GraphQL解析器

时间:2018-03-23 10:30:44

标签: schema graphql resolver

我正在尝试将GraphQL架构语言作为工作项目的一部分。我想遇到问题,因为我不确定如何为我需要使用的特定数据结构编写解析器。我有一些我正在写的预约管理系统的数据。此时有三个集合 - 员工帐户预订。典型json数据的简化版本如下所示:

Staff: {
    id: 0,
    Name: 'Joe Blogs',
    Speciality: 'Fitter'
}

Account: {
    id: 0,
    Name: 'Fred Foo',
    Company: 'Acme Holdings',
    staffId: 0
}

Booking: {
    id: 0,
    Date: '2018-03-23',
    staffId: 0,
    accountId: 0,
    AssignedStaff: [
        {id: 0, staffId: 1},
        {id: 1, staffId: 3}
    ]
}

因此,预订将与特定帐户相关,并由特定员工拥有。它还将分配任意数量的其他工作人员。我的GraphQL架构如下所示:

type Staff {
    id: Int!
    Name: String!
    Speciality: String!
    accounts: [Account]
    bookings: [Booking]
}

type Account {
    id: Int!
    Name: String!
    Company: String!
    staff: Staff!
    bookings: [Booking]
}

type Booking {
    id: Int!
    Date: String!
    staff: Staff!
    account: Account!
    AssignedStaff: [AssignedStaff]
}

type AssignedStaff {
    id: Int!
    staff: Staff!
}

我为员工帐户以及预订之间的关系工作解决方案。我遇到问题的地方是在预订时为指定的工作人员编写解析器。我正在使用静态虚拟数据进行开发。工作解析器功能如下所示:

Account: {
    bookings (account) {
        return booking.filter(booking => booking.accountId === account.id)
    },
    staff (account) {
        return staff.find(staff => staff.id === account.staffId)
    }
},
Booking: {
    account (booking) {
        return account.find(account => account.id === booking.accountId)
    },
    staff (booking) {
        return staff.find(staff => staff.id === booking.staffId)
    }
},
Staff: {
    accounts (staff) {
        return account.filter(account => account.staffId === staff.id)
    },
    bookings (staff) {
        return booking.filter(booking => booking.staffId === staff.id)
    }
}

他们工作正常。我可以做,例如像这样的查询:

staff(id: 0){
    Name
    accounts {
        Name
        bookings {
            Date
        }
    }
}

并且它有效,返回的数据正是我所期望的。当我尝试在预订时返回有关指定员工的数据时,会出现问题。我有AssignedStaff的解析器,目前看起来像这样:

AssignedPhotographer: {
    staff(booking) {
        return staff.filter(staff => staff.id === booking.AssignedStaff.staffId)
    }
}

但是当我像这样对它运行查询时:

staff(id: 0){
    Name
    accounts {
        Name
        bookings {
            Date
            AssignedStaff {
                staff{
                    Name
                }
            }
        }
    }
}

我得到的数据有一个AssignedStaff的空值数组。空值的数量与预订的分配人员数量相匹配,但似乎没有正确链接到员工类型。如果我只是要求指定工作人员的ID进行这样的预订:

staff(id: 0){
    Name
    accounts {
        Name
        bookings {
            Date
            AssignedStaff {
                id
            }
        }
    }
}

它工作正常,并返回正确的数据。我猜这个问题与我完成解析器的方式有关,可能与AssignedStaff解析器有关。谁能告诉我我做错了什么?

1 个答案:

答案 0 :(得分:1)

您有任何Staff个对象可供过滤,然后尝试以AssignedStaff数组的形式返回。 StaffAssignedStaff不会共享除id之外的任何字段 - 这就是为什么您会看到id字段已填充而非staff字段。

GraphQL期待这样的数组:

[ { id, staff } ]

你正在传递它

[ { id, name, speciality } ]

您需要修改您的解析器,看起来像这样:

return staff
  .filter(s => s.id === booking.AssignedStaff.staffId)
  .map(f => ({ id: f.id, staff: f }))

我不知道AssignedStaff.id和AssignedStaff.staff.id之间的预期差异是什么(如果有的话),所以你可能需要摆弄上面的代码,但它应该给你一个起点。