我使用graphql-sequelize来实现GraphQL端点。我刚刚创建了一个新的辅助实体并将其与我的一个主要实体相关联,现在我正在尝试在获取主要实体时包含相关的辅助实体。当我尝试实现该提取时,我收到以下错误:
AssertionError ERR_ASSERTION Include support has been removed in favor of dataloader batching
我的旧的基于解析器的gql端点看起来像这样:
driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver)
}
我从代码库中其他地方的实验中了解到这通常有效:
const driver = Driver.getById(`${uuid}`, {
include: { model: Helmet }
})
// yields:
// {
// id: '<uuid>',
// name: 'Tom',
// helmetNumber: '470',
// Helmet: {
// number: '470',
// type: 'cool',
// color: 'red'
// }
// }
因此,在检查source code of graphql-sequelize's resolver
并确定第二个参数传递给sqlz访问器之后,我将相同的include
添加到我的GQL解析器中,如下所示:
driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {
include: { model: Helmet }
})
}
当我得到致命的错误时。研究表明,graphql-sequelize人员现在不允许performance reasons使用a cryptic comment,而是支持sequelize的数据加载器,我目前没有使用它,也没有计划使用。
但即使我这样,也没有回答他们希望我们如何在include
内获取相关行的问题。我发现http://sqlfiddle.com/#!9/649ef3/1表示有一个名为resolver
的替代品,但我还没有能够找到它的文档,而且从臀部开始射击失败了:
join
我所能想到的就是添加一个driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {
include: { model: Helmet } // fatal error: disallowed
join: { model: Helmet } // no effect, no error
join: Helmet // no effect, no error
})
}
例程来手动获取相关模型,然后将该结果附加到主模型中,如果以标准方式获取它,它将出现在同一个地方(即使用after
),如下所示:
include
当代码执行并找到我期望的模型时,它无法将找到的模型附加到同一个地方。
Sqlz实例不是普通哈希:它们具有driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {
// can't do this:
include: { model: Helmet }
// so I try to emulate it this way:
after: async (driver) => {
driver.Helmet = await driver.getHelmet()
return driver
}
})
}
属性,其中包含数据库中的原始列值,当您引用dataValues
时,隐藏的getter从{{1}获取值}。实验表明,通过myModel.colName
的急切加载会导致相关模型出现在myModel.dataValues[ colName ]
结构中,可能与所需的任何隐藏访问器一起出现,如下所示:
include
我很确定我可以在那里附加获取的模型:
dataValues
但我认为我们应该避免摆弄{
dataValues: {
id: '<uuid>',
name: 'Tom',
helmetNumber: '470',
Helmet: {
dataValues: {
number: '470,
type: 'cool',
color: 'red'
}
}
}
}
,而这似乎是ham骂。
我正在使用driver.dataValues.Helmet = await driver.getHelmet()
,它(正确地)根据GQL架构验证解析器返回值,因此,dataValues
的GQL类型定义在技术上是 downstream < / em>这个解析函数。我已经开始为构建GQL类型构建一堆糖(特别是在初级实体中嵌入辅助实体时),这种观点鼓励我认为基于apollo-server-express
的端点应该统一 - 形状的回报。即如果某些实体的解析器发出破坏的sqlz模型实例,而其他实体返回健康的实例,则会很糟糕。
我们如何在没有Driver
的graphql-sequelize resolver
中实现预先加载?
包装版本:
resolver
答案 0 :(得分:1)
我尝试了两件事:
driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {
after: driver => {
return Driver.findById(driver.id, {
include: [ Helmet ]
})
}
})
}
这样可行,但它会两次击中主表,这是 mega gross。
所以,我决定抛出graphql-sequelize的“helper”resolver
,并直接编程到apollo-server-express的API:
driver: {
type: MyGQLTypes.Driver,
resolve: (parent, args, context, info) => {
return Driver.findById(args.id, {
include: [ Helmet ]
})
})
}
像冠军一样工作。可能有一个我还没有看到的缺点。我想时间会证明。
让这个开放一段时间以防其他人有更好的答案(包括我自己)。