Building a GraphQL API with Magnolia CMS

Joaquín Alfaro
The Startup
Published in
5 min readApr 27, 2020

In this article I will show how to create a GraphQL API using the headless features of Magnolia CMS.

GraphQL

GraphQL is a query language for APIs defined by Facebook to solve some issues of traditional REST APIs as flexibility and simplicity.

All the resources of the API are exposed in a single request — normally a POST to /graphql — and the content is a query using GraphQL specification. The query specifies the filter and the data to be returned by the API. Below you can find an example to query the detail of a film:

query {
films(id: "english-patient") {
director,
duration,
summary
actors {
name,
gender,
role
}
}
}

In case that actors were not required, just remove the actors field from the query — In case of REST API it would be necessary to implement a new endpoint —

In addition to queries, GraphQL provides Mutation for requests of creation, update and delete resources and Subscription for realtime queries.

For more details about the specification of GraphQL you can visit the official website of GraphQL

Magnolia CMS

Magnolia CMS is an open source CMS developed in Java and focused on headless skills, that makes it really easy and cheap to create API’s to query and manage the contents in the CMS.

Magnolia Delivery endpoint API

Delivery endpoint API is a powerful feature of Magnolia that allows the creation of an API in declarative way just with a .yaml file.

Below you can see an example of definition of Delivery endpoint.

class: info.magnolia.rest.delivery.jcr.v2.JcrDeliveryEndpointDefinition
nodeTypes:
- mgnl:content
includeSystemProperties: false
bypassWorkspaceAcls: false
limit: 50
workspace: tours
references:
- name: tourTypes
propertyName: tourTypes
referenceResolver:
class: info.magnolia.rest.reference.jcr.JcrReferenceResolverDefinition
targetWorkspace: category

For more details about Delivery endpoint API you can visit the official documentation of Magnolia CMS

Java-based REST endpoint

As Magnolia CMS is open source and developed in Java, it is possible to implement a traditional java-based REST the same way as any java service.

At this entry of the documentation of Magnolia can be found the guidelines to create a java-based REST in Magnolia How to create a custom Java-based REST endpoint

Implementation of magnolia-rest-graphql

magnolia-rest-graphql is a custom module of Magnolia that implements a GraphQL API for contents in Magnolia CMS.

Casting

GraphQL spec (June 2018) as specification of GraphQL

Magnolia CMS 6.1 as GraphQL API server

graphql-java 14.0 as java implementation of GraphQL. Awesome library that implements GraphQL specs for java.

Features

Requirements and features of magnolia-rest-graphql

  • Expose endpoint for GraphQL queries.
  • Register GraphQL schemas as resources of Magnolia.
  • Create GraphQL schemas for registered Delivery endpoints. This feature will allow to get Delivery endpoints as GraphQL Queries
  • Graph Query field to make queries directly on JCR repository. It will be the GraphQL version of Nodes endpoint API

Endpoint for GraphQL queries

The module magnolia-rest-graphql exposes the endpoint POST /.rest/magnolia-rest-graphql/graphql to handle GraphQL requests. The endpoint is implemented as a Java-based REST endpoint in the class GraphQLEndpoint

GraphQLEndpoint — POST /magnolia-rest-graphql/graphql

GraphQL schemas as resources of Magnolia

The schema of GraphQL types must be defined into the resources folder /graphqls in a similar way as restEndpoints.

my-light-module/├── decorations├── dialogs├── graphqls│   ├── pages.graphql│   └── tours.graphql├── i18n├── restEndpoints│   └── pages_v1.yaml├── templates└── webresources

The schemas must be written using SDL (Schema Definition Language) and the query fields must use the directive @definition to specify the workspace, root path and nodetypes of the query. Below you can see an example to execute queries in the workspace website for nodetypes mgnl:page

GraphQL schemas for registered RestEndpoints

Delivery endpoints are mapped with GraphQL schemas to allow querying the same resources with GraphQL requests.

For every delivery endpoint is created a Query field named <delivery endpoint> and tagged with the directive @delivery to specify the workspace, root path and nodeTypes of the queries. The value of the arguments are taken from the Delivery endpoint definition.

Below you can see an example of the GraphQL schema generated from a registered Delivery endpoint:

Example of query based on the example below:

POST /.rest/magnolia-rest-graphql/graphql

query {
delivery_tours_v1 {
name,
properties {
name,
string
}
}
}

GET /.rest/delivery/tours/v1

Graph Query field to execute queries on JCR repository

Magnolia provides the Nodes endpoint API to access and manipulate JCR Nodes, the module magnolia-rest-graphql provides the query field nodes to execute same kind of queries.

“nodes” field in Query type

Example of request to query the pages inside /travel folder:

POST /.rest/magnolia-rest-graphql/graphql

query {
nodes(workspace: "website", path: "/travel") {
name,
nodeType,
path,
children {
properties {
name,
string
}
}
}
}

GET http://localhost:8080/magnolia-rest-graphql-bundle/.rest/nodes/v1/website/travel

Usage

First. Adds the dependency of magnolia-rest-graphql to the bundle of magnolia:

<!-- magnolia-rest-graphql -->
<dependency>
<groupId>com.formentor</groupId>
<artifactId>magnolia-rest-graphql</artifactId>
<version>${magnolia-rest-graphql.version}</version>
</dependency>

Second. Creates the folder /graphqls in a light-module or java module

my-light-module/├── decorations├── dialogs├── graphqls├── i18n├── restEndpoints├── templates└── webresources

Third. Design your own query fields and add the .graphql files to /graphqls folder

Fourth. Check the schema with your favourite GraphQL client— I will use GraphQL Playground

Checking schema from GraphQL Playground

Fifth. Build and execute your queries easily from GraphQL client

Executing queries using GraphQL Playground

Example using Apollo client

Dependencies:

npm i apollo-cache-inmemory apollo-client apollo-link-http graphql graphql-tag isomorphic-unfetch

Apollo client to magnolia-rest-graphql resources

nextjs page that renders content queried to Magnolia:

Resources and references

Github of the module magnolia-rest-graphql

Github of a bundle of magnolia using magnolia-rest-graphql

--

--