Caching AEM GraphQL queries with content fragment


Problem Statement:

How can I persist query?

How to cache my query results?
How to Update my queries?


Requirement:

Provide details on how to add the persist graphql query, cache the results from graphql and update the persisted query

Provide curl commands to execute in terminal or on postman


Introduction:

Persisted Queries (Caching)

After preparing a query with a POST request, it can be executed with a GET request that can be cached by HTTP caches or a CDN.

This is required as POST queries are usually not cached, and if using GET with the query as a parameter there is a significant risk of the parameter becoming too large for HTTP services and intermediates.

Persisted queries must always use the endpoint related to the appropriate Sites configuration; so, they can use either, or both:

  • Specific Sites configuration and endpoint

Creating a persisted query for a specific Sites configuration requires a corresponding Sites-configuration-specific endpoint (to provide access to the related Content Fragment Models).

For example, to create a persisted query specifically for the SampleGraphQL Sites configuration:

a corresponding SampleGraphQL-specific Sites configuration

  • Go to the tools section for the aem and general section and select Configuration Browser as shown below
Configuration browser
  • Add select the conf folder and go to the properties and make GraphQL Persistent Queries checkbox is checked
Enable persistent queries

a SampleGraphQL-specific endpoint must be created in advance.

  • Go to tools section for the aem and assets section and select GraphQL as shown below
assets -> graphql
  • Add the new end point as shown below:
endpoint

Add the following CORS configurations for the GraphQL API calls:

CORS config

Register graphql search path:

Register Servlet path

Here are the steps required to persist a given query:

Prepare the query by putting it to the new endpoint URL /graphql/persist.json/<config>/<persisted-label>.

For example, create a persisted query:

curl -u admin:admin -X PUT 'http://localhost:4502/graphql/persist.json/SampleGraphQL/cities' \
--header 'Content-Type: application/json' \
--data-raw '{
  cityList {
    items {
      _path
      name
      country
      population
    }
  }
}'
  • At this point, check the response.

For example, check for success:

{
    "action": "create",
    "configurationName": "SampleGraphQL",
    "name": "cities",
    "shortPath": "/SampleGraphQL/cities",
    "path": "/conf/SampleGraphQL/settings/graphql/persistentQueries/cities"
}

You can then replay the persisted query by getting the URL /graphql/execute.json/<shortPath>.

For example, use the persisted query:

curl -u admin:admin -X GET 'http://localhost:4502/graphql/execute.json/SampleGraphQL/cities' \
--header 'Authorization: Basic YWRtaW46YWRtaW4='

Update a persisted query by POSTing to an already existing query path.

For example, use the persisted query:

curl -u admin:admin -X POST 'http://localhost:4502/graphql/persist.json/SampleGraphQL/cities' \
--header 'Content-Type: application/json' \
--data-raw '{
  cityList {
    items {
      _path
      name
      country
      population
    }
  }
}'

Create a wrapped plain query.

For example:

curl -u admin:admin -X PUT 'http://localhost:4502/graphql/persist.json/SampleGraphQL/plain-cities' \
--header 'Content-Type: application/json' \
--data-raw '{ "query": "{cityList { items { _path name country country population } } }"}'

Create a wrapped plain query with cache control.

For example:

curl -u admin:admin -X PUT 'http://localhost:4502/graphql/persist.json/SampleGraphQL/plain-cities-max-age' \
--header 'Content-Type: application/json' \
--data-raw '{ "query": "{cityList { items { _path name country country population } } }", "cache-control": { "max-age": 300 }}'

Create a persisted query with parameters:

For example:

curl -u admin:admin -X PUT 'http://localhost:4502/graphql/persist.json/SampleGraphQL/plain-cities-query-parameters' \
--header 'Content-Type: application/json' \
--data-raw \
'query GetAsGraphqlModelTestByPath($apath: String!) {
    cityByPath(_path: $apath) {
        item {
        _path
        name
        country
        population
        }
    }
  }'

Executing a query with parameters.

For example:

curl -u admin:admin -X POST \
    -H "Content-Type: application/json" \
    "http://localhost:4502/graphql/execute.json/SampleGraphQL/plain-cities-query-parameters;apath=%2Fcontent%2Fdam%2Fsample-content-fragments%2Fcities%2Fberlin"

curl -u admin:admin -X GET \
    "http://localhost:4502/graphql/execute.json/SampleGraphQL/plain-cities-query-parameters;apath=%2Fcontent%2Fdam%2Fsample-content-fragments%2Fcities%2Fberlin"

AEM Content Fragments with GraphQL – Getting started with GraphQL

Problem Statement:

What is GraphQL?

How GraphQL can be used with Content Fragments?

Introduction:

What is GraphQL?

GraphQL is a query language for APIs and provides a complete and understandable description of the data in your API.

For example:

Let’s consider an external system with the following tables:

1 to 1 relationship between Company table with person table and 1 to 1 person table with awards table.

If I need to get all awards

You might be doing a call to

{domain}/api/awards

awards API flow

To get individual person and awards

{domain}/api/persons?personID{ID}&awards={ID}

person API flow

To get individual company and person and awards

{domain}/api/company?companyNam={NAME}personID={ID}&awards={ID}

Company API flow

But in GraphQL you can send the parameters like a query and get all the related content as well

GraphQL API flow

To use Graph QL you need to prepare schemas and based on the schema you can do filter the data.

For more information on GraphQL, you can be visiting the link

Benefits:

  • Avoiding iterative API requests as with REST,
  • Ensuring that delivery is limited to the specific requirements,
  • Allowing for bulk delivery of exactly what is needed for rendering as the response to a single API query.

How GraphQL can be used with Content Fragments?

GraphQL is a strongly 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 do this, a client needs to 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.

Content Fragments can be used as a basis for GraphQL for AEM queries as:

  • They enable you to design, create, curate and publish page-independent content.
  • The Content Fragment Models provide the required structure by means of defined data types.
  • The Fragment Reference, available when defining a model, can be used to define additional layers of structure.
Model References provided by Adobe

Content Fragments

  • Contain structured content.
  • They are based on a Content Fragment Model, which predefines the structure for the resulting fragment.

Content Fragment Models

  • Are used to generate the Schemas, once Enabled.
  • Provide the data types and fields required for GraphQL. They ensure that your application only requests what is possible, and receives what is expected.
  • The data type Fragment References can be used in your model to reference another Content Fragment, and so introduce additional levels of structure.

Fragment References

  • Is of particular interest in conjunction with GraphQL.
  • Is a specific data type that can be used when defining a Content Fragment Model.
  • References another fragment, dependent on a specific Content Fragment Model.
  • Allows you to retrieve structured data.
    • When defined as a multifeed, multiple sub-fragments can be referenced (retrieved) by the prime fragment.

JSON Preview

To help with designing and developing your Content Fragment Models, you can preview JSON output.

Install:

  1. AEM 6.5.11 (aem-service-pkg-6.5.11.zip)
  2. Graph QL OAK Index (cfm-graphql-index-def-1.0.0.zip)
  3. GraphiQL Developer tool (graphiql-0.0.6.zip)

For AEMacS you will get the content fragment with the latest update.

Go to configuration folder

  1. AEM tools section
  2. General selection in sidebar
  3. Configuration bowser

As shown below:

Configuration Folder

Create a configuration folder and select

  1. Content Fragment Models
  2. GraphQL Persistent Queries

As shown below:

Create a Conf folder with required checkboxes

Go to Assets Model:

  1. AEM tools section
  2. Assets selection in sidebar
  3. Content Fragments Model

As shown below:

Go to Assets CF

Select the folder and create the content fragments as shown below:

CF models

You can also install the package attached here

Go to the following URL to access the GraphiQL developer tool and run the following query:

Note: you can also get all the autosuggestions by using the ctrl+space shortcut

{
  cityByPath(_path: "/content/dam/sample-content-fragments/cities/berlin") {
    item {
      _path
      name
      country
      population
      categories
    }
  }
}
GraphiQL developer tool

Download Sample Package here

You can also find more queries and filters in the following link