GraphQL

  Written by The Jahia Team
 
Developers
   Estimated reading time:

1 Introduction

GraphQL provides an alternative to a REST / CRUD model that allows more flexibility in the query, manipulation of the contents and services called. It provides a full framework, with cache capabilities and extensions, all fully integrated within DX.
Please consult http://graphql.org/learn/ to understand GraphQL concepts.

2 GraphQL integration in DX

In its current state, the DX GraphQL API support only content queries. Modifications (mutations) will be part of a future release.

2.1 OSGi bundles

DX comes several GraphQL OSGi bundles.

2.1.1 Graphql-java

https://github.com/Jahia/graphql-java

This is the Java implementation of GraphQL specifications

2.1.2 Graphql-java-servlet

https://github.com/Jahia/graphql-java-servlet
This bundle provides the following GraphQL endpoint:

/{context}/modules/graphql

2.1.3 Graphql-java.annotations:

https://github.com/Jahia/graphql-java-annotations
This bundle provides annotations for GraphQL integration.

2.2 DX module

2.2.1 Graphql-core:

https://github.com/Jahia/graphql-core/tree/master/graphql-dxm-provider
In its current state, the module provides all JCR reading capabilities using GraphQL.

3 GraphQL JCR Implementation

We provide a jcr implementation that allows to perform queries against the repository. This implementation adds support to Relay (http://facebook.github.io/relay/docs/en/introduction-to-relay.html)

3.1 JCR Query

3.1.1 Workspace

All queries are prefixed by

jcr (workspace: LIVE|EDIT) {
}

workspace is an optional parameter that specifies the workspace on which the query will be executed. If not set, the DEFAULT workspace is used.

3.1.2 Session

The session (logged user) used is the JCR Session used in the HTTP request.

3.1.3 JCRQuery

We provide various fields/methods to query the JCR:

  • nodeById
  • nodeByPath
  •  nodesById
  • nodesByPath
  • nodesByQuery
  • nodeTypeByName
  • nodeTypes

Each field can have its own parameters or can define filters.
Using GraphiQL you can get the documentation regarding the parameters and returned values of each of these fields.

3.1.4 Internationalization

I18n is supported, content in a specific language can be found using the language parameter on displayName, properties and property fields.
Example:

{ jcr(workspace: EDIT)
    { nodeByPath(path: "/sites/digitall/home") {
        displayName(language: "en")
    }
}

3.1.5 Permissions

As we are using the JCR session from the http session, permissions are natively supported.

3.1.6 Sample queries

{ jcr(workspace: EDIT) { nodeByPath(path: "/sites/digitall/home") {
      children(typesFilter: {types: ["jnt:page"]}) {
        nodes {
          name
          name_en: displayName(language: "en")
          name_fr: displayName(language: "fr")
          createdBy: property(name: "jcr:createdBy") {
            value
          }
          descendants(limit: 2, typesFilter: {types: ["jmix:list"]}) {
            nodes {
              path
            }
          }
          ancestors(upToPath: "/sites") {
            path
          }
        }
      }
    }
}
}

{ jcr(workspace: LIVE)  {
nodesByQuery(query: "select * from [jnt:page]", offset: 2, limit: 10) {
      edges {
        index
        cursor
        node {
          displayName(language: "en")
        }
      }
    }
}
}

{ jcr(workspace: EDIT) { nodeByPath(path: "/sites/digitall/home") {
      children(typesFilter: {types: ["jnt:page"]}, propertiesFilter: {filters: [{property: "j:templateName", value: "home"}]}) {
        nodes {
          name
          name_en: displayName(language: "en")
          name_fr: displayName(language: "fr")
          createdBy: property(name: "jcr:createdBy") {
            value
        }
          template: property(name: "j:templateName") {
            value
          }
      }
    }
}
}
}

3.2 GraphiQL

GraphiQL is a graphical tool that helps building GraphQL queries.
The tool is available here: http://{hostname}:{port}/{context}/modules/graphql-dxm-provider/tools/graphiql.jsp

4 GraphQL in custom modules

4.1 GraphQL in views

A simple way to use GraphQL in DX views is to call the GraphQL endpoint with an ajax request.
You can first use GraphiQL to build your query and then use it in your view:

<script>
    var graphQLQuery =  '{  jcr {   nodesByPath(paths: "/sites/") {    children {     nodes {      path      name     }    }   }  } } '
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'json';
    xhr.open("POST", "/modules/graphql");
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.setRequestHeader("Accept", "application/json");
    xhr.onload = function () {
        console.log('data returned:', xhr.response);
    }
    xhr.send(JSON.stringify({query: graphQLQuery}));
</script>
Note that you can use any framework (jQuery, etc ..) to simplify this code.

For integration with modern js frameworks (react, angular, etc ..) you can use Apollo JS client:
https://github.com/apollographql/apollo-client

4.2 GraphQL extensions

It is possible for a DX module to extend the GraphQL grammar, the same way as we did for the JCR implementation.
Example:
https://github.com/Jahia/graphql-core/tree/master/graphql-extension-example

5 GraphQL configuration

The configuration file contains the matching permission for a field type (Class / method). A module can provide its own configuration for the field types it provides.
A default configuration file is available here:

/digital-factory-data/karaf/etc/org.jahia.modules.graphql.provider-default.cfg

To build your own configuration, add the configuration file in your project, prefix its name by: org.jahia.modules.graphql.provider- and edit the pom.xml of your module to reference it.
For example:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>attach-artifacts</id>
            <phase>package</phase>
            <goals>
                <goal>attach-artifact</goal>
            </goals>
            <configuration>
                <artifacts>
                    <artifact>
                        <file>
                            src/main/resources/META-INF/configurations/org.jahia.modules.graphql.provider-custom.cfg
                        </file>
                        <type>cfg</type>
                        <classifier>graphql-cfg</classifier>
                    </artifact>
                </artifacts>
            </configuration>
        </execution>
    </executions>
</plugin>

A full example is available here:
https://github.com/Jahia/graphql-core/blob/master/graphql-dxm-provider/pom.xml