Grapher and GraphQL Schema Directives
Wouldn't it be sweet if we could setup our collections and links in our GraphQL type definitions?
Yes, it would be very sweet.
Install
meteor add cultofcoders:grapher-schema-directives
Sample
Where you define your types:
1type User @mongo(name: "users") { 2 comments: [Comment] @link(to: "user") 3} 4 5type Comment @mongo(name: "comments") { 6 user: User @link(field: "userId") 7 post: Post @link(field: "commentId") 8 createdAt: Date @map("created_at") 9} 10 11type Post @mongo(name: "posts") { 12 comments: [Comment] @link(to="post") 13}
In the background, the schema directives analyze our types and create propper links, when we have a field
present, that's going to be a main link, that's the collection we are going to store it in, when we have to
present, that's going to be an inversed link.
Direct fields are automatically indexed by default. You don't have to specify index: true
Options to direct links:
1@map(field: "linkStorageField", autoremove: true, unique: true, metadata: true)
For more information about options, refer to Grapher API
Each ObjectType
needs to have the propper @mongo
directive to work.
The @map
directive makes a database field be aliased. The reason for this is that when we query with Grapher's GraphQL abilities to properly adapt that field to the correspondant db field. In the backscene, we basically have a reducer
.
Usage
1import { 2 directives, // the full map of the directive, as mentioned in the sample above 3 directiveDefinitions, // the definitions 4 MapToDirective, // the actual directive classes 5 LinkDirective, 6 MongoDirective, 7} from 'meteor/cultofcoders:grapher-schema-directives'; 8 9// Add them to your graphql servers
If you are using cultofcoders:apollo
package, this is done by default, you don't have to care about it.
This is a very quick way to setup your schema, however if you need to use denormalisation abilities, and you don't want to give up the sugary directives above:
1import { db } from 'meteor/cultofcoders:grapher'; 2 3Meteor.startup(() => { 4 const userCommentLinker = db.users.getLinker('comments'); 5 Object.assign(userCommentLinker.linkConfig, { 6 denormalize: {}, 7 }); 8 userCommentLinker._initDenormalization(); 9});