FAQs about implementing headless using Content Fragments and GraphQL


Nested Content Fragment Models (Solution for composite multifields)

  • Content Fragment Models can utilize the “Fragment References” data type to establish connections with other Content Fragments, introducing additional layers of structure and relationships.
  • Any relationships between Content Fragment Models are depicted in the schema as fields, allowing clients to effortlessly navigate these connections.
  • When you find the need to create composite multifield within a Content Fragment, consider using nested Content Fragments.
    • Example: Imagine you’re working on a content management system for a travel website, and you need to create CF for displaying destinations. Each destination includes Title and list of ‘places to visit’ (an image and a description). With nested Content Fragments, you can structure it like this:
      • Parent Fragment – Destination:
        • Title (Text)
        • Places to Visit (Multifield Fragment Reference)

  • Child Fragment – Places to visit:
    • Image (Content Reference)
    • Description (Text)

One should now be able to configure multiple “Places to visit” for a “Destination

  • Using nested Content Fragments in this way allows you to maintain a structured, organized, and reusable content model for your travel website. You can also write and execute more refined queries involving destination and places-to-visit

GraphQL Data Access: Authentication with Access Tokens and Credentials (AEMaaCS, AMS and local)

To access data through GraphQL, it’s necessary to provide authentication details, which may include:

  • Access tokens for AEM as a Cloud Service (AEMaaCS) and AEM 6.5.
  • Credentials for local development.

These authentication measures ensure that only authorized actions are permitted, creating a secure and traceable method for external applications to interact with AEM. Access tokens are mandatory for both the creation and execution of GraphQL queries.

For detailed instructions on generating Access Tokens, please refer to the following resources:

What are main issues that result in slow GraphQL queries?

  • Large data set size, due to inefficient pagination and filterning
  • Large result set size

For more details on how to optimize, refer to link.

How to improve GraphQL Performance via Caching?

Client Side:

  1. Local Query Result Caching: Implement local caching mechanisms on client devices. When a GraphQL query fetches data, store the results locally. The next time the same query is requested, check if the data is available in the local cache before making a network request. This minimizes redundant network calls and speeds up response times.
  2. Data Deduplication: Deduplicate data in the cache to avoid storing the same information multiple times. Use identifiers or keys to index cached data for efficient retrieval.
  3. Query Batching: Combine multiple GraphQL queries into a single request when possible. This reduces the overhead of multiple network requests, especially in scenarios where clients require data from various parts of the schema.

CDN (Caching of Assets and Query Responses):Leverage Content Delivery Networks (CDNs) to cache static assets like images. CDNs distribute content across globally distributed servers, reducing the latency of asset retrieval for clients.

Dispatcher (Caching of Assets and Query Responses):

  1. Cache Invalidation Strategies: Implement cache invalidation strategies to ensure that cached data remains up-to-date. Use cache headers, time-to-live (TTL) settings to trigger cache purges when data changes. Cache without CORS reponse headers
  2. Response Compression: Enable response compression on your GraphQL server to reduce the size of data transferred over the network. This is particularly important for large query responses.

Also visit Basic Guidelines: Content Fragment Models and GraphQL Queries for AEM Headless Implementation for more suggestions

How to enable/configure caching of GraphQL queries in AEMaaCS?

Enable caching for Persisted Queries on AEMaaCS

By default, caching for persisted queries is not activated in the Dispatcher. Enabling it as the default setting is not possible because customers using CORS (Cross-Origin Resource Sharing) with multiple origins may need to review and potentially adjust their Dispatcher configuration. For instructions on how to enable caching, please consult link

Setting specific TTL for GraphQL queries

The AEM GraphQL API allows you to update the default cache-control parameters to your queries in order to improve performance. But , we can override the same using  GraphiQL Explorer. For details, please refer to link

How to configure caching of GraphQL queries in AEM 6.5?

For AEM 6.5, the cache-control header for persisted query is set via following OSGi service

Dispatcher configs needed:

Append following to the rewrite rules:

RewriteCond %{REQUEST_URI} ^/graphql/execute.json
RewriteRule ^/(.*)$ /$1;.json [PT]

Add following to filters section:

/0502 { /type "allow" /extension "json" /path "/graphql/execute" /method "GET" }

Cache invalidation of GraphQL Persisted queries

1. Dispatcher Cache Invalidation for GraphQL Persisted Queries

The Dispatcher cache for GraphQL Persisted Queries doesn’t automatically invalidate after content fragments are activated. It is recommended to rely on Time-to-Live (TTL) cache control headers to wait for Dispatcher Cache Invalidation to take effect after activation or deactivation.

2. CDN Cache Invalidation during Activation/Deactivation

The CDN is not automatically flushed after Dispatcher cache invalidation. It is advised to rely on TTL in cache control headers to await CDN Cache Invalidation after activation or deactivation. The CDN cache should automatically refresh after the TTL expires, fetching new content from the origin servers.

3. Explicit Invalidation of the Dispatcher Cache

For explicitly validating dispatcher cache, refer to:

It’s important to note that the CDN is not flushed automatically when the Dispatcher is invalidated. The CDN respects TTLs, eliminating the need for explicit flushing.

4. Explicit invalidation of dispatcher and Fastly cache for AEMaaCS.

Please refer to link

What are the general guidelines for designing Content Fragment Models or GraphQL queries?

Please refer to Basic Guidelines: Content Fragment Models and GraphQL Queries for AEM Headless Implementation

What are the APIs to access/manipulate Content fragments?

How to access GraphQL Schema?

To access the GraphQL Schema, you can utilize the endpoint API through http://<host><endpoint-url>.GQLschema. For instance: http://localhost:4502/content/cq:graphql/wknd-shared/endpoint.GQLschema.

Additionally, you can retrieve specific schema conveniently using the GraphiQL explorer at http://localhost:4502/aem/graphiql.html.

How to access GraphQL Schema Errors?

To manage schema errors, you can retrieve them via http://<host><endpoint-url>.schemaerrors.

How can I consume the content from AEM in a headless way?

You can build front-end applications (e.g., React, Angular) that make GraphQL requests to AEM to fetch and display content fragments.

Here are AEM Headless Client that can used to execute the GraphQL queries and map data to power the app.

What Sets GraphQL Apart from Servlet-Based API / Assets HTTP API ?

Say you have a RESTful API for querying articles, complete with multiple filtering parameters like authorFirstName, authorLastName, and slug. In a RESTful context, crafting intricate URLs with query parameters might look something like this:

GET /api/article?authorFirstName=Stacey&authorLastName=Roswells&slug=alaskan-adventures

Now, let’s explore how GraphQL simplifies this process through structured and efficient querying:

query getArticleByAuthor($authorFirstName: String!, $authorLastName: String!) {
  articleList(
    filter: {
      authorFragment: {
        firstName: {_expressions: [{value: $authorFirstName}]},
        lastName: {_expressions: [{value: $authorLastName}]}
      }
    }
  ) {
    items {
      _path
      title
      slug
      main {
        json
      }
      authorFragment {
        firstName
        lastName
        profilePicture {
          ... on ImageRef {
            _path
            _dynamicUrl
          }
        }
      }
    }
  }
}

1. Structured Queries: GraphQL queries allow for explicit structuring of requests. You precisely define which fields you want from the server. This clarity is evident in the query, where you list the desired fields like `_path`, `title`, `slug`, and more. This structured approach eliminates the need for crafting convoluted query string parameters as seen in traditional HTTP requests.

2. No Over-fetching or Under-fetching: GraphQL ensures that you receive only the data you explicitly request. In the provided query, you’ve specified fields such as `title`, `slug`, `firstName`, and `lastName`. You won’t receive any surplus data beyond what you’ve outlined in the query. This eradicates the common issues of over-fetching (unnecessary data retrieval) and under-fetching (insufficient data) associated with RESTful APIs.

3. Nested Queries: GraphQL supports nested queries, enabling you to request related data within a single query. In the GraphQL query example, you not only retrieve article data but also seamlessly fetch author-related information in the same query. This eliminates the necessity for multiple HTTP requests to acquire associated data, simplifying the overall data retrieval process.

4. Strong Typing: GraphQL enforces a robust typing system. Within your query, you’ve defined variables like `$authorFirstName` and `$authorLastName` with specific types (both are of type `String!`, indicating they are mandatory and must be strings). This strong typing ensures a shared understanding between the client and server regarding the data types in use, reducing ambiguity and errors when constructing requests.

In summary, GraphQL’s structured and expressive querying approach empowers you to craft precise queries, reducing unnecessary data transmission and enabling the retrieval of related data within a single request. Its robust typing system enhances clarity and reliability in the query, making GraphQL a potent tool for modern application development.

References:

3 thoughts on “FAQs about implementing headless using Content Fragments and GraphQL

  1. Thank You for your insights on AEM headless. A FAQ guide on implementing a headless approach using content fragments and GraphQL, offeringa FAQble insights for developers and content strategists exploring decoupled architectures in AEM.
    Its systematic addressing of frequently asked questions, covering a range of topics from the basics of content fragments and GraphQL to more nuanced considerations like caching strategies and handling complex content structures. This organized format makes the information accessible and serves as a quick reference for those navigating the complexities of headless AEM implementations.
    The emphasis on the synergy between content fragments and GraphQL is particularly insightful. By showcasing how these technologies can work in tandem, the article provides a holistic view of the headless architecture, offering practical advice on structuring content for flexibility and efficiency.
    Readers can gain a deeper understanding of how to leverage content fragments and GraphQL to create dynamic, engaging experiences, making it easier to envision and implement similar solutions in their AEM projects.
    It is a valuable resource for professionals engaged in headless AEM implementations. Its comprehensive FAQ format, insightful explanations, and practical examples make it an indispensable guide for those seeking clarity on content fragments, GraphQL, and the broader landscape of headless CMS in Adobe Experience Manager.

    Like

Leave a comment