处理GraphQL中的Mongoose填充字段

时间:2017-01-01 13:57:12

标签: node.js mongodb mongoose graphql graphql-js

如何表示可以是简单ObjectId字符串或填充对象实体的字段?

我有一个Mongoose Schema,表示“设备类型”,如下所示

// assetSchema.js

import * as mongoose from 'mongoose'
const Schema = mongoose.Schema;

var Asset = new Schema({  name : String,
                          linked_device: { type: Schema.Types.ObjectId, 
                                           ref: 'Asset'})

export AssetSchema = mongoose.model('Asset', Asset);

我正在尝试将其建模为GraphQLObjectType,但我很难理解如何允许linked_ue字段采用两种类型的值,一种是ObjectId,另一种是完整的{{} 1}}对象(填充时)

Asset

我已经研究了联盟类型,但问题是联盟类型期望字段被定义为其定义的一部分,而在上述情况下,// graphql-asset-type.js import { GraphQLObjectType, GraphQLString } from 'graphql' export var GQAssetType = new GraphQLObjectType({ name: 'Asset', fields: () => ({ name: GraphQLString, linked_device: ____________ // stumped by this }); 字段下面没有字段{ {1}}对应一个简单的linked_device

有什么想法吗?

2 个答案:

答案 0 :(得分:7)

事实上,您可以对linked_device字段使用unioninterface类型。

使用联合类型,您可以按如下方式实现GQAssetType

// graphql-asset-type.js

import { GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql'

var LinkedDeviceType = new GraphQLUnionType({
  name: 'Linked Device',
  types: [ ObjectIdType, GQAssetType ],
  resolveType(value) {
    if (value instanceof ObjectId) {
      return ObjectIdType;
    }
    if (value instanceof Asset) {
      return GQAssetType;
    }
  }
});

export var GQAssetType = new GraphQLObjectType({
  name: 'Asset',
  fields: () => ({
    name: { type: GraphQLString },
    linked_device: { type: LinkedDeviceType },
  })
});

看看这个优秀的article on GraphQL union and interface

答案 1 :(得分:3)

当我遇到这篇文章时,我试图解决拉动关系数据的一般问题。为了清楚起见,原始问题似乎是当字段可能包含ObjectId或Object时如何动态解析数据,但是我不相信它的优秀设计首先要有一个字段存储object或objectId。因此,我有兴趣解决简化的场景,我将字段分开 - 一个用于Id,另一个用于对象。我也认为使用Unions过于复杂,除非你实际上有另一个场景,如上面引用的文档中描述的场景。我认为下面的解决方案也可能让其他人感兴趣......

注意:我使用的是graphql-tools,因此我的类型是编写的模式语言语法。因此,如果您的用户类型包含以下字段:

type User {
    _id: ID
    firstName: String
    lastName: String
    companyId: ID
    company: Company
}

然后在我的用户解析器功能代码中,我添加了这个:

  User: {   // <-- this refers to the User Type in Graphql
    company(u) {   // <-- this refers to the company field
      return User.findOne({ _id: u.companyId }); // <-- mongoose User type
    },
  }

上述内容与用户解析器功能一起使用,并允许您编写如下的GQL查询:

query getUserById($_id:ID!) 
    { getUserById(_id:$_id) {
    _id
    firstName
    lastName
    company {
        name
    }
    companyId
    }}

此致

S上。 Arora的