从带有子字段的猫鼬模式生成 Graphql 类型
Generate Graphql Type from mongoose schema with subfields
我开始使用 NodeJS 和 Mongoose 构建一个 Graphql 服务以与已经在生产中的 REST api 一起使用,但我在寻找一种方法来翻译我的猫鼬模式时遇到了一些麻烦到 GraphQL 类型。
我有以下架构:
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});
所以,基本上,问题出在 history
字段上。该字段是一个包含 2 个子字段的对象列表:订单(引用另一个猫鼬模式的对象列表)和餐厅(引用餐厅的猫鼬模式)。
我的主要问题是:在为 "User" 编写相应的 GraphQL 类型时,有没有办法创建子字段,就像我在 history
字段上使用 mongoose 所做的那样,或者我必须创建第二个类型然后引用这个类型(知道应用程序不需要在猫鼬中创建另一个模式,它只能在 GraphQL 中创建)。
正如您所说,当您编写 GraphQL 模式时,历史记录需要是一个单独的类型,Order 和 Restaurant 可能也是如此。使用 Apollo,模式类型定义类似于:
type User {
# additional fields
history: [Record!]!
}
type Record {
orders: [Order!]!
restaurant: Restaurant
}
除了上面的类型定义之外,您还需要为 User 提供一个解析器。在这种情况下,解析器将简单地 return User.findOne()
(或者您通常从数据库中获取用户对象)。
这是最巧妙的部分:您甚至可能不需要订单、餐厅甚至历史记录的解析器。当您不指定解析器时,GraphQL 将使用默认解析器,该解析器愉快地使用它传递的对象(无论您将在解析器中为 User 类型传递的 User 对象的任何块)。如果它在该对象中找到与您在 GraphQL 模式中指定的字段匹配的键
类型定义,它将填充这些字段并忽略其他所有内容。
当然,如果您需要额外的控制(可能您的对象键和字段名称不匹配),您仍然可以自己编写解析器。
我开始使用 NodeJS 和 Mongoose 构建一个 Graphql 服务以与已经在生产中的 REST api 一起使用,但我在寻找一种方法来翻译我的猫鼬模式时遇到了一些麻烦到 GraphQL 类型。
我有以下架构:
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});
所以,基本上,问题出在 history
字段上。该字段是一个包含 2 个子字段的对象列表:订单(引用另一个猫鼬模式的对象列表)和餐厅(引用餐厅的猫鼬模式)。
我的主要问题是:在为 "User" 编写相应的 GraphQL 类型时,有没有办法创建子字段,就像我在 history
字段上使用 mongoose 所做的那样,或者我必须创建第二个类型然后引用这个类型(知道应用程序不需要在猫鼬中创建另一个模式,它只能在 GraphQL 中创建)。
正如您所说,当您编写 GraphQL 模式时,历史记录需要是一个单独的类型,Order 和 Restaurant 可能也是如此。使用 Apollo,模式类型定义类似于:
type User {
# additional fields
history: [Record!]!
}
type Record {
orders: [Order!]!
restaurant: Restaurant
}
除了上面的类型定义之外,您还需要为 User 提供一个解析器。在这种情况下,解析器将简单地 return User.findOne()
(或者您通常从数据库中获取用户对象)。
这是最巧妙的部分:您甚至可能不需要订单、餐厅甚至历史记录的解析器。当您不指定解析器时,GraphQL 将使用默认解析器,该解析器愉快地使用它传递的对象(无论您将在解析器中为 User 类型传递的 User 对象的任何块)。如果它在该对象中找到与您在 GraphQL 模式中指定的字段匹配的键 类型定义,它将填充这些字段并忽略其他所有内容。
当然,如果您需要额外的控制(可能您的对象键和字段名称不匹配),您仍然可以自己编写解析器。