【问题标题】:GraphQL Resolver for Nested Array of Objects用于嵌套对象数组的 GraphQL 解析器
【发布时间】:2018-09-02 00:11:06
【问题描述】:

作为工作项目的一部分,我正在尝试掌握 GraphQL 模式语言。我认为我遇到了问题,因为我不确定如何为我需要使用的特定数据结构编写解析器。我有一些我正在编写的约会管理系统的数据。此时有三个集合 - StaffAccountBooking。典型 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!
}

对于员工帐户Booking之间的关系,我有工作解决程序正常工作。我遇到问题的地方是为预订中的指定员工编写解析器。我目前正在使用静态虚拟数据进行开发。工作解析器函数如下所示:

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 解析器有关。谁能告诉我我做错了什么?

【问题讨论】:

  • staff.filter(staff => staff.id === booking.Photographers.staffId) 不应该是 staff.filter(staff => staff.id === booking.staffId)?跨度>
  • 每个预订都有一个所有者 staffId,以及任意数量的其他 AssignedStaff,它们都需要链接到相同的员工数据。我使用 staff.filter(staff => staff.id === booking.staffId) 来解决预订和预订所有者之间的链接,这工作正常,但我还需要在数组中获取有关员工的员工数据指定的工作人员。 (稍微编辑问题,以便所有字段名称匹配)

标签: schema graphql resolver


【解决方案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 之间的预期区别(如果有的话)是什么,所以您可能需要修改上面的代码,但它应该会给您一个起点。

【讨论】:

  • 嗨丹尼尔,这肯定让我更接近了。我从 AssignedStaff 中删除了 id 属性,因此它现在只包含 StaffId 以将其链接到 Staff 类型。我还在 map 函数中插入了一个 console.log 以查看“f”是什么,它由正确的 AssignedStaff 的 Staff 类型对象组成,但是,尽管查询现在返回一个 Staff prop,其中 Name 仍然为空。 {“数据”:{“预订”:{“日期”:“2018-03-01”,“AssignedStaff”:[{“员工”:{“姓名”:空}}]}}}
猜你喜欢
  • 2018-08-27
  • 2018-08-25
  • 2019-12-21
  • 2017-01-07
  • 2019-10-14
  • 2017-06-03
  • 2012-10-17
  • 2021-07-28
  • 1970-01-01
相关资源
最近更新 更多