使用子字段从mongoose模式生成Graphql类型
我开始使用NodeJS和Mongoose构建一个Graphql服务,与已经在生产中的restapi一起使用,但是我在找到将Mongoose模式转换为Graphql类型的方法时遇到了一些困难 我有以下模式:使用子字段从mongoose模式生成Graphql类型,mongoose,graphql,graphql-js,Mongoose,Graphql,Graphql Js,我开始使用NodeJS和Mongoose构建一个Graphql服务,与已经在生产中的restapi一起使用,但是我在找到将Mongoose模式转换为Graphql类型的方法时遇到了一些困难 我有以下模式: var userSchema = new mongoose.Schema({ name: {type: String, required: true}, email: {type: String}, imageURL: {type: String, default:nu
var userSchema = new mongoose.Schema({
name: {type: String, required: true},
email: {type: String},
imageURL: {type: String, default:null},
providerId: {type: String, required: true},
token: {type: String, required: true},
history: [{
orders:[{type: mongoose.Types.ObjectId, ref:'Order'}],
restaurant: {type: mongoose.Types.ObjectId, ref: 'Restaurant'}
}]
}, { timestamps: true});
因此,基本上,问题在于历史
字段。此字段是一个包含两个子字段的对象列表:orders(引用另一个mongoose模式的对象列表)和restaurant(引用restaurant的mongoose模式)
我的主要问题是:在为“User”编写相应的GraphQL类型时,是否有一种方法可以创建子字段,就像我在
history
字段中对mongoose所做的那样,或者我必须创建第二种类型,然后引用此类型(知道应用程序不需要在mongoose中创建另一个模式,而只需要在GraphQL中创建)。正如您所说,当您编写GraphQL模式时,历史记录将需要是一个单独的类型,就像Order和Restaurant一样。使用Apollo,模式类型定义将类似于:
type User {
# additional fields
history: [Record!]!
}
type Record {
orders: [Order!]!
restaurant: Restaurant
}
除了上面的类型定义之外,您还将为用户提供一个解析器。在这种情况下,解析器只需返回User.findOne()
(或者您通常从数据库获取用户对象的方式)
这里有一个巧妙的部分:您甚至可能不需要订单、餐厅甚至历史记录的解析程序。当您不指定解析程序时,GraphQL将使用默认的解析程序,该解析程序愉快地使用它所传递的对象(您将在用户类型的解析程序中传递的任何用户对象块)。如果它在该对象中找到与GraphQL架构的
类型定义,它将填充这些字段并忽略其他所有内容
当然,如果您需要额外的控制(可能您的对象键和字段名不匹配),您仍然可以自己编写解析器。我的疑问是,我是否需要为历史创建一个单独的类型,因为我没有在Mongoose中创建。所以我会这样做。谢谢您的帮助explanation@ThiagoNascimento你可以用一个代替,但你严重限制了什么可以要求(即,任何请求该字段的人都无法将其进一步缩小到仅限于餐厅,或仅限于每个订单中的几个字段)。您还失去了在历史记录中轻松删除或模拟单个字段的能力。我不知道这一点,但我可能会选择单独的类型,以便在请求中具有更大的灵活性。还有一个问题:当使用mongoose ObjectID引用mongoose对象时,我是否必须在graphql解析器中填充该字段?因此可能会有一些问题类似于:User.find().populate(fields)是的,您可能需要为引用MongoDB中其他文档的任何字段调用populate。假设您让默认解析程序完成大部分繁重的工作,您将希望查询的解析程序返回与您在模式中概述的结构匹配的对象。