Extending the schema
Contents
The default Guillotine provides fields based on the available schemas.
Sometimes you might want to add/modify/delete fields (new retrieval methods, search in a separate database, virtual fields, etc…).
The Guillotine schema is entirely configurable. When creating a schema, you can define a listener for a GraphQL type. This listener will be called before the type is created and given the possibility to modify the type creation parameters.
Example: Adding fields
In this example, we have the Author and Post types. But we wish to apply the following modifications:
-
Author should have a new field "fullName" that is the concatenation of firstName and lastName
-
Author data field "email" should require admin rights to be retrieved.
-
Author data field "birthDate" should not be accessible through the GraphQL API.
-
Author should have a new field "posts" returning all the blog posts written by an author
var contentLib = require('/lib/xp/content');
var guillotineLib = require('/lib/guillotine');
var graphQlLib = require('/lib/graphql');
var schema = guillotineLib.createSchema({
creationCallbacks: {
'com_enonic_app_myapp_Author_Data': function(context, params){ (1)
params.fields.fullName = { (2)
type: graphQlLib.GraphQLString,
resolve: function (env) {
return env.source.firstName + ' ' + env.source.lastName;
}
};
params.fields.email.resolve = function (env) { (3)
return authLib.hasRole('system.admin') ? env.source.email : null
};
delete params.fields.birthDate; (4)
},
'com_enonic_app_myapp_Author': function(context, params){ (1)
params.fields.posts = { (5)
type: graphQlLib.list(graphQlLib.reference('com_enonic_app_myapp_Post')),
resolve: function (env) {
return contentLib.query({
contentTypes: [app.name + ":Post"],
filters: {
hasValue: {
field: "data.author",
values: [env.source._id]
}
}
}).hits;
}
};
}
}
);
exports.post = function (req) {
var body = JSON.parse(req.body);
var result = graphQlLib.execute(schema, body.query, body.variables);
return {
contentType: 'application/json',
body: JSON.stringify(result)
};
};
1 | Passes a callback that will be called before the creation of the specified GraphQL type. It receives the Guillotine context and the object type creation parameters. |
2 | Adds a new string field "fullName" concatenating two other fields. The resolution function will query contents of type post having the current author ID as field "data.author" |
3 | Overwrites the resolution function of an existing field "email" |
4 | Deletes an existing field "birthDate" |
5 | Adds a new field "posts" returning a list of posts. |
These are only examples. You could also modify the type Query
and add an entire new API next to the Headless CMS API.