The GraphQL API

GraphQL is:

  • …a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API. It gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.”.

    See GraphQL.org

  • …an open spec for a flexible API layer. Put GraphQL over your existing backends so you can build products faster than ever before…”.

    See Explore GraphQL.

  • “…a data query language and specification developed internally by Facebook in 2012 before being publicly open-sourced in 2015. It provides an alternative to REST-based architectures with the purpose of increasing developer productivity and minimizing amounts of data transferred. GraphQL is used in production by hundreds of organizations of all sizes…”

    See GraphQL Foundation.

For further information about the GraphQL API, see the following sections (among many other resources):

The GraphQL for AEM implementation is based on the standard GraphQL Java™ Library. See:

GraphQL Terminology

GraphQL uses the following:

See the (GraphQL.org) Introduction to GraphQL for comprehensive details, including the Best Practices.

GraphQL Query Types

With GraphQL you can perform queries to return either:

AEM provides capabilities to convert queries (both types) to Persisted Queries that are cached by Dispatcher and the CDN.

GraphQL Query Best Practices (Dispatcher and CDN)

Persisted queries are the recommended method to be used on publish instances as:

  • they are cached
  • they are managed centrally by AEM
NOTE
Usually there is no dispatcher/CDN on author, so there is no performance gain in using persisted queries there; apart from testing them.

GraphQL queries using POST requests are not recommended as they are not cached, so on a default instance the Dispatcher is configured to block such queries.

While GraphQL also supports GET requests, these requests can hit limits (for example, the length of the URL) that can be avoided using persisted queries.

See Enable caching of persisted queries for further details.

NOTE
The ability to perform direct queries may be deprecated at some point in the future.

GraphiQL Interface

An implementation of the standard GraphiQL interface is available for use with AEM GraphQL.

NOTE
GraphiQL is included in all environments of AEM (but is only accessible/visible when you configure your endpoints).
In previous releases, you needed a package to install the GraphiQL IDE. If you have this package installed, it can now be removed.

This interface lets you directly input, and test, queries.

For example:

  • http://localhost:4502/content/graphiql.html

It provides features such as syntax-highlighting, auto-complete, auto-suggest, together with a history and online documentation:

GraphiQL Interface

Use Cases for Author and Publish Environments

The use cases can depend on the type of AEM environment:

  • Publish environment; used to:

    • Query data for JS application (standard use-case)
  • Author environment; used to:

    • Query data for “content management purposes”:

      • GraphQL in AEM is a read-only API.
      • The REST API can be used for CR(u)D operations.

Permissions

The permissions are required for accessing Assets.

GraphQL queries are run with the permission of the AEM user of the underlying request. If the user does not have read access to some fragments (stored as Assets), they do not become part of the result set.

Also, the user must have access to a GraphQL endpoint to be able to run GraphQL queries.

Schema Generation

GraphQL is a typed API, which means that data must be clearly structured and organized by type.

The GraphQL specification provides a series of guidelines on how to create a robust API for interrogating data on a certain instance. To complete these guidelines, a client must fetch the Schema, which contains all the types necessary for a query.

For Content Fragments, the GraphQL schemas (structure and types) are based on Enabled Content Fragment Models and their data types.

CAUTION
All the GraphQL schemas (derived from Content Fragment Models that have been Enabled) are readable through the GraphQL endpoint.
This ability means that you must ensure that no sensitive data is available, as it could be leaked this way. For example, it includes information that could be present as field names in the model definition.

For example, if a user created a Content Fragment Model called Article, then AEM generates a GraphQL type ArticleModel. The fields within this type correspond to the fields and data types defined in the model. In addition, it creates some entrypoints for the queries that operate on this type, such as articleByPath or articleList.

  1. A Content Fragment Model:

    Content Fragment Model for use with GraphQL

  2. The corresponding GraphQL schema (output from GraphiQL automatic documentation):
    GraphQL Schema based on Content Fragment Model

    This image shows that the generated type ArticleModel contains several fields.

    • Three of them have been controlled by the user: author, main, and referencearticle.

    • The other fields were added automatically by AEM, and represent helpful methods to provide information about a certain Content Fragment. In this example,
      (the helper fields) _path, _metadata, _variations.

  3. After a user creates a Content Fragment based on the Article model, it can then be interrogated through GraphQL. For examples, see the Sample Queries (based on a sample Content Fragment structure for use with GraphQL).

In GraphQL for AEM, the schema is flexible. This flexibility means that it is auto-generated each time a Content Fragment Model is created, updated, or deleted. The data schema caches are also refreshed when you update a Content Fragment Model.

The Sites GraphQL service listens (in the background) for any modifications made to a Content Fragment Model. When updates are detected, only that part of the schema is regenerated. This optimization saves time and provides stability.

So for example, if you:

  1. Install a package containing Content-Fragment-Model-1 and Content-Fragment-Model-2:

    1. GraphQL types for Model-1 and Model-2 are generated.
  2. Then modify Content-Fragment-Model-2:

    1. Only the Model-2 GraphQL type gets updated.

    2. Whereas Model-1 remains the same.

NOTE
This detail is important to note just in case you want to do bulk updates on Content Fragment Models through the REST api, or otherwise.

The schema is served through the same endpoint as the GraphQL queries, with the client handling the fact that the schema is called with the extension GQLschema. For example, performing a simple GET request on /content/cq:graphql/global/endpoint.GQLschema results in the output of the schema with the Content-type: text/x-graphql-schema;charset=iso-8859-1.