How do I represent a field that could be either a simple ObjectId
string or a populated Object Entity?
I have a Mongoose Schema that represents a \'Device t
I was trying to solve the general problem of pulling relational data when I came across this article. To be clear, the original question appears to be how to dynamically resolve data when the field may contain either the ObjectId or the Object, however I don't believe it's good design in the first place to have a field store either object or objectId. Accordingly, I was interested in solving the simplified scenario where I keep the fields separated -- one for the Id, and the other for the object. I also, thought employing Unions was overly complex unless you actually have another scenario like those described in the docs referenced above. I figured the solution below may interest others also...
Note: I'm using graphql-tools so my types are written schema language syntax. So, if you have a User Type that has fields like this:
type User {
_id: ID
firstName: String
lastName: String
companyId: ID
company: Company
}
Then in my user resolver functions code, I add this:
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
},
}
The above works alongside the User resolver functions already in place, and allow you write GQL queries like this:
query getUserById($_id:ID!)
{ getUserById(_id:$_id) {
_id
firstName
lastName
company {
name
}
companyId
}}
Regards,
S. Arora
As a matter of fact, you can use union or interface type for linked_device
field.
Using union type, you can implement GQAssetType
as follows:
// 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 },
})
});
Check out this excellent article on GraphQL union and interface.