1
votes

I'm starting to build a Graphql service to go alongside with a REST api already in production, using NodeJS and Mongoose, but I'm having some trouble in finding a way to translate my mongoose schema to a GraphQL type.

I have the following schema:

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});

So, basically, the trouble is the history field. This field is a list an object with 2 subfields: orders (list of Objects that reference another mongoose schema) and restaurant (that reference the mongoose schema for restaurant).

My main question is: when writing the corresponding GraphQL type for "User", is there a way to create subfields, as I did with mongoose on the history field, or I have to create a second Type and then reference this type (knowing that there's no need for the application to create another schema in mongoose, whould only create in GraphQL).

1

1 Answers

1
votes

Like you said, when you write your GraphQL schema, history will need to be a separate type, as will probably Order and Restaurant. Using Apollo, the schema type definitions would look something like:

type User {
  # additional fields
  history: [Record!]!
}

type Record {
  orders: [Order!]!
  restaurant: Restaurant
}

In addition to the type definitions above, you would also provide a resolver for User. In this case, the resolver would simply return User.findOne() (or however you normally get the User object from your database).

Here's the neat part: you may not even need resolvers for Order, Restaurant or even History. When you don't specify a resolver, GraphQL will use a default resolver that happily uses the object it's passed (whatever chunk of the User object you would pass in your resolver for the User type). If it finds keys in that object that match the fields in you specified in your GraphQL schema's type definition, it will populate those fields and ignore everything else.

Of course, if you need additional control (maybe your object keys and field names don't match), you can always still write the resolver yourself.