从带有子字段的猫鼬模式生成 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 模式中指定的字段匹配的键 类型定义,它将填充这些字段并忽略其他所有内容。

当然,如果您需要额外的控制(可能您的对象键和字段名称不匹配),您仍然可以自己编写解析器。