2017-01-01 6 views
4

Как представить поле, которое может быть либо простой строкой ObjectId, либо заполненной объектной сущностью?Обработка полей, заполненных Mongoose в GraphQL

У меня есть Mongoose схемы, которая представляет собой «тип устройства» следующим образом

// 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, а другие полным 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 
}); 

Я посмотрел в Тип Союза, но проблема в том, что тип Союз ожидает полей оговориться в рамках его определение, тогда как в случае вышеизложенного нет полей под полем linked_device, когда linked_device соответствует простому ObjectId.

Любые идеи?

ответ

4

На самом деле вы можете использовать union или interface тип для поля linked_device.

Используя тип соединения, вы можете реализовать 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.

+0

Спасибо за помощь @AhmadFerdous. Вопрос в строке 'value instanceof Objectid', что такое' ObjectId'? Это 'var ObjectId = mongoose.Schema.Types.ObjectId'? Также как выглядит 'ObjectIdType'? – techtrek

+1

Да, это мангуста ObjectId. 'ObjectIdType' - это просто тип объекта GraphQL для оболочки, который может иметь строковое поле для идентификатора. –

+0

Спасибо @AhmadFerdous, это действительно полезно.Я также задал еще один вопрос, с которым вы могли бы помочь, действительно оцените поддержку: http://stackoverflow.com/questions/41427320/how-to-handle-hyphens-in-graphql-schema-definitions – techtrek

3

Я пытался решить общую проблему вытягивания реляционных данных, когда я столкнулся с этой статьей. Чтобы быть ясным, исходный вопрос заключается в том, как динамически разрешать данные, когда поле может содержать ObjectId или Object, однако я не считаю, что это хороший дизайн, в первую очередь, для хранения поля либо объекта, либо objectId. Соответственно, я был заинтересован в решении упрощенного сценария, где я сохраняю поля разделенными - один для Id, а другой для объекта. Я также думал, что использование Unions слишком сложно, если у вас нет другого сценария, подобного описанному в документах, упомянутых выше. Я понял, что решение ниже может заинтересовать и других ...

Примечание: Я использую инструменты graphql, поэтому мои типы пишут синтаксис языка схемы. Таким образом, если у вас есть тип пользователя, который имеет такие поля, как это:

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

+0

Это не похоже на ответ на этот вопрос. Если у вас есть ответ на другой вопрос, попробуйте найти вопрос, который фактически задает вопрос, на который вы хотите ответить, и разместите свой ответ. Если такой вопрос не существует, вы можете опубликовать его самостоятельно, если считаете его полезным. Обратите внимание, что все ответы должны быть направлены на то, чтобы ответить на вопрос сверху, а не только на некоторые связанные вопросы. –

+0

Его попытка ответить на то, что, вероятно, является основной задачей ... вопрос был задан и ответил, как было задано ... но я пытаюсь пересмотреть вопрос, который должен задать правильный вопрос, и опросить помещение. Нехороший дизайн - иметь хранилище полей как объекта, так и объекта, поэтому я предлагаю, чтобы был более эффективный подход с более простым ответом. Просто мысль. – sarora

+0

А, ок. Вы можете сделать это более ясным в самом ответе. –