¿Cómo represento un campo que podría ser una cadena de ObjectId simple o una entidad de objeto poblada?
Tengo un Esquema Mongoose que representa un 'Tipo de dispositivo' de la siguiente manera
// 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); Estoy tratando de modelar esto como un GraphQLObjectType pero no sé cómo permitir que el campo linked_ue tome dos tipos de valores, uno es un ObjectId y el otro es un objeto de Asset completo (cuando está poblado)
// graphql-asset-type.js import { GraphQLObjectType, GraphQLString } from 'graphql' export var GQAssetType = new GraphQLObjectType({ name: 'Asset', fields: () => ({ name: GraphQLString, linked_device: ____________ // stumped by this }); He investigado los Tipos de Unión, pero el problema es que un Tipo de Unión espera que los campos se estipulen como parte de su definición, mientras que en el caso anterior, no hay campos debajo del campo de linked_device vinculado cuando el linked_device corresponde a un ObjectId simple.
¿Algunas ideas?
De hecho, puede usar el tipo de interfaz o unión para el campo linked_device .
Con el tipo de unión, puede implementar GQAssetType de la siguiente manera:
// 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 }, }) });Consulte este excelente artículo sobre la unión y la interfaz de GraphQL .
Estaba tratando de resolver el problema general de extraer datos relacionales cuando encontré este artículo. Para ser claros, la pregunta original parece ser cómo resolver dinámicamente los datos cuando el campo puede contener el ObjectId o el Object, sin embargo, no creo que sea un buen diseño en primer lugar tener un campo que almacene un objeto o un objectId. En consecuencia, estaba interesado en resolver el escenario simplificado donde mantengo los campos separados, uno para el Id y el otro para el objeto. También pensé que emplear sindicatos era demasiado complejo a menos que realmente tenga otro escenario como los descritos en los documentos a los que se hace referencia anteriormente. Pensé que la solución a continuación puede interesar a otros también...
Nota: estoy usando herramientas de graphql, por lo que mis tipos están escritos en sintaxis de lenguaje de esquema. Entonces, si tiene un tipo de usuario que tiene campos como este:
type User { _id: ID firstName: String lastName: String companyId: ID company: Company }Luego, en mi código de funciones de resolución de usuario, agrego esto:
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 }, }Lo anterior funciona junto con las funciones de resolución de usuario que ya existen y le permite escribir consultas GQL como esta:
query getUserById($_id:ID!) { getUserById(_id:$_id) { _id firstName lastName company { name } companyId }}Saludos,
S.Arora