Upgrade Notes

Contents

Global Schema

The Guillotine API is now Global, meaning the schema will include types and extensions for all installed applications, regardless of the context you use to access the API.

Subscriptions

Due to limited interest and use, Subscriptions have been removed from Guillotine 7.

Guillotine 7 does not provide a way to add custom subscriptions at the moment. If you need subscriptions, this will require you to build a custom API, consider using the Guillotine 6 code as a foundation.

Deprecated fields

The query and queryConnection fields are deprecated. Use queryDsl and queryDslConnection instead.

Url fields

The params argument of URL field (i,e, pageUrl, imageUrl, attachmentUrl and mediaUrl) were previously of type String, but are now of type JSON.

  • Old way: pageUrl(params: String)

{
  guillotine {
    get(key: "/path/to/content") {
      pageUrl(params: "{\"a\": [1, 4], \"b\": 2, \"c\": 3 }")
    }
  }
}
  • New way: pageUrl(params: JSON)

{
  guillotine {
    get(key: "/path/to/content") {
      pageUrl(params: {a: [1, 4], b: 2, c: 3})
    }
  }
}

Guillotine library

Guillotine 7 now supports dynamically extending and augmenting of the API. As a result the Guillotine library has been discontinued.

If you have been using the Guillotine library, and want to keep similar funcitonality with v7, you will have to migrate to the new way of extending.

Legacy options like allowPaths and subscriptionEventTypes are no longer supported either.

Remember, you can still install Guillotine 7, and keep your old library-based application in the same Enonic instance.

Migrating

In order to migrate your code, you will have to:

  1. Create a new application or use an existing one, where you should create guillotine.js file in the src/main/resources/guillotine folder of your project.

  2. This file must contain a function that returns an object with structure which described here.

  3. Your schema will be available at the POST /site/<project-name>/<branch-name> endpoint. More information here.

Let see important changes in the new version of the Guillotine application related with creationCallbacks:

  • In Guillotine application you can not define dataFetcher directly in creationCallbacks, you must use resolvers node instead. That done to separate model from logic.

  • To add, modify or remove fields you must use addFileds, modifyFields and removeFields functions of the params object respectively.

  • To set description of the type you must use setDescription function of the params object.

  • To set interfaces of the type you must use setInterfaces function of the params object.

  • You can not rename field anymore.

More information about creationCallbacks can be found here.

Example of migration

Now let see the example of migration from the Guillotine library to the Guillotine application.

Let’s assume that we have the following creationCallbacks in our code when using the Guillotine library:

const authLib = require('/lib/xp/auth');
const guillotineLib = require('/lib/guillotine');
const graphQlLib = require('/lib/graphql');

const schema = guillotineLib.createSchema({
    creationCallbacks: {
        'com_enonic_app_myapp_Author_Data': function(context, params){
            params.fields.fullName = { (1)
                 type: graphQlLib.GraphQLString,
                 resolve: function (env) {
                     return env.source.firstName + ' ' + env.source.lastName;
                 }
            };

            params.fields.email.resolve = function (env) { (2)
                return authLib.hasRole('system.admin') ? env.source.email : null;
            };

            delete params.fields.birthDate; (3)
        },
    }
});

In this example we made the following changes:

1 Added a new fullName field to the com_enonic_app_myapp_Author_Data type. Pay attention that the declaration of the field is done by declaring a data fetcher.
2 Override the default data fetcher with our own data fetcher containing custom logic.
3 Removed the birthDate field from com_enonic_app_myapp_Author_Data type.

Now, let’s see how to migrate this code using extensions from the Guillotine application:

First what we need to create a guillotine.js file in the src/main/resources/guillotine folder. Then we can make the same changes for com_enonic_app_myapp_Author_Data type, but in the different way.

const authLib = require('/lib/xp/auth');

exports.extensions = function (graphQL) { (1)
    return {
        creationCallbacks: {
            com_enonic_app_myapp_Author_Data: function (params) { (2)
                params.addFields({
                    fullName: { (3)
                        type: graphQL.GraphQLString,
                    }
                });

                params.removeFields(['birthDate']); (4)
            },
        },
        resolvers: {
            com_enonic_app_myapp_Author_Data: { (5)
                fullName: function (env) {
                    return env.source.firstName + ' ' + env.source.lastName;
                },
                email: function (env) {
                    return authLib.hasRole('system.admin') ? env.source.email : null;
                }
            }
        },
    }
};

This code has the following important things:

1 Inside the extenstions function we will return object with creationCallbacks and resolvers properties.
2 To make changes for com_enonic_app_myapp_Author_Data type in the creationCallbacks we need to add the property as named function com_enonic_app_myapp_Author_Data which has the params argument. Using params object we can add, modify and remove fields, set description and override interfaces for type.
3 Then we add the fullName field with String type and without arguments.
4 Then we remove birthDate field. The removeFields function applies an arrays of string with field names which must be removed.
5 Then to set a data fetcher for fullName and email fields we must use the resolvers property of the returned object. Where in the same way, inside the resolvers property we must define the com_enonic_app_myapp_Author_Data object with respectively properties as field names and implement data fetcher functions.

That it, our migration is done.

Visit the extensions documentation for more details.


Contents

Contents