Customizing the schema
Contents
Customizing the schema
This section describes how to customize your schema deployment
Integrating Guillotine to an existing schema
You may have an existing GraphQL schema and wish to integrate Guillotine to this schema. In that case, use the functions createContext
and createHeadlessCmsType
instead of createSchema
Example
var guillotineLib = require('/lib/guillotine');
var graphQlLib = require('/lib/graphql');
var schema = createSchema();
exports.post = function (req) {
var body = JSON.parse(req.body);
var result = graphQlLib.execute(schema, body.query, body.variables);
return {
contentType: 'application/json',
body: result
};
};
function createSchema() {
var context = guillotineLib.createContext(); (1)
return context.schemaGenerator.createSchema({
query: createRootQueryType(context),
dictionary: context.dictionary (2)
});
}
function createRootQueryType(context) {
return context.schemaGenerator.createObjectType({
name: 'Query',
fields: {
guillotine: {
type: guillotineLib.createHeadlessCmsType(context), (3)
resolve: function () {
return {};
}
}
}
});
}
1 | Creates the context necessary to create Guillotine types. |
2 | Passes the dictionary to the schema creation. The use of a dictionary is necessary to define interface implementations. |
3 | Creates the Guillotine Headless CMS type |
Extending the schema
The default Guillotine schema provides fields based on the content type schemas. But you might want to add/modify/delete fields (new retrieval methods, search in a separate database, virtual fields, …).
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.
GraphQL - Enonic XP Library
A library has been implemented to facilitate the creation of a GraphQL service on Enonic XP: |
Example
In this example, we have the types Author and Post generated. 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 = JSON.stringify(graphQlLib.execute(schema, body.query, body.variables));
return {
contentType: 'application/json',
body: 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.