AEM GraphQL

Learn how AEM's GraphQL API enables headless content delivery from Content Fragments to any channel or application.

Last reviewed: December 2024

·AEM 6.5 SP7+AEM as a Cloud Service
✅
Quick Understanding: AEM's GraphQL API lets you query Content Fragments and deliver structured content to any application — React apps, mobile apps, digital signage, or any system that can make HTTP requests. It's how you use AEM as a "headless" CMS.

🔍 What Is It?

AEM provides a GraphQL endpoint that exposes Content Fragment data. Key concepts:

  • →GraphQL Endpoint — /content/cq:graphql/global/endpoint.json (or custom endpoints)
  • →Persisted Queries — Pre-saved GraphQL queries accessible via simple GET URLs
  • →Content Fragment Models — Define the GraphQL schema automatically
  • →Delivery API — Read-only API for fetching content (not for mutations)

Each Content Fragment Model automatically generates GraphQL types. An "Article" model generates ArticleModel, ArticleModelList, ArticleByPath, etc.

🎯 Why Do We Need It?

GraphQL enables the headless and hybrid AEM patterns:

  • →Headless — React/Vue/Angular apps fetch content via GraphQL, render their own UI
  • →Hybrid — Some pages use AEM page editor; some sections fetch via GraphQL
  • →Omnichannel — Same content delivered to web, mobile, kiosk, voice assistants
  • →Performance — Fetch exactly the fields you need, no over-fetching

🏗️ What Happens in Real Projects?

Real Project: React App consuming AEM Content

  1. Content team creates "Product" fragments in AEM
  2. React developer writes a GraphQL query to fetch products
  3. React app calls the persisted query endpoint
  4. AEM returns JSON with exactly the requested fields
  5. React renders the product listing

Persisted Query URL:

GET /graphql/execute.json/mysite/product-listing

This URL is cacheable by CDN and Dispatcher — much better than ad-hoc POST queries.

⚙️ How It Works

Query Types:

  • →{ModelName}ByPath — Fetch single fragment by path
  • →{ModelName}List — Fetch multiple fragments with filtering/sorting
  • →{ModelName}Paginated — Paginated results

Filtering:

{
  articleList(
    filter: { category: { _expressions: [{ value: "Technology" }] } }
    sort: "publishDate DESC"
    limit: 10
    offset: 0
  ) { items { title publishDate } }
}

Authentication:

For public content: no auth needed (if content is published)

For preview/draft content: use AEM authentication tokens

💻 Example

GraphQL Queries in Practice — Common GraphQL patterns for AEM Content Fragments.

graphql
# Fetch article list with filtering
query GetTechArticles {
  articleList(
    filter: {
      category: {
        _expressions: [{ value: "Technology", _operator: EQUALS }]
      }
      _path: { _expressions: [{ value: "/content/dam/mysite/articles", _operator: STARTS_WITH }] }
    }
    sort: "publishDate DESC"
    limit: 12
  ) {
    items {
      _path
      headline
      publishDate
      category
      author {
        ... on AuthorModel {
          name
          photo { _path }
        }
      }
      featuredImage {
        _path
        width
        height
      }
      body {
        plaintext
      }
    }
    _count
  }
}

🤔 Common Confusions

❓ What is the difference between ad-hoc queries and persisted queries?

Ad-hoc queries are POST requests with the query in the body — flexible but not cacheable. Persisted queries are pre-saved on the server and accessed via GET URLs — cacheable by Dispatcher and CDN. Always use persisted queries in production.

❓ Can I use GraphQL to create or update content?

No. AEM's GraphQL API is read-only. It's for content delivery, not content management. To create or update content programmatically, use AEM's REST APIs (Assets HTTP API, Sites API) or Sling POST Servlet.

🚨 Common Production Issues

GraphQL endpoint returns 404

GraphQL feature not enabled, or endpoint not configured. Enable in Tools → Assets → Content Fragment Models.

Query returns null for fragment references

the referenced fragment is not published. Publish all fragments in the reference chain.

CORS errors in browser

configure CORS settings in AEM's OSGi configuration for the GraphQL endpoint.

Slow queries

no pagination, fetching too many fragments. Add limit/offset and use persisted queries.

Persisted query works on Author but fails on Publish

the query, endpoint configuration, Content Fragment Models, or referenced fragments were not published.

GraphQL blocked by Dispatcher

filters do not allow the persisted query execution path or the endpoint-specific URL pattern.

CDN serves stale GraphQL data

persisted query cache headers or invalidation rules do not match the freshness requirement for that content type.

Nested fragment queries become slow

the model allows deep references and the query fetches more fields than the channel actually needs.

✅ Best Practices

Always use persisted queries in production

they're cacheable and prevent arbitrary query execution.

Design Content Fragment Models with GraphQL in mind

the model IS the API schema.

Use fragment references to create relationships, but avoid deep nesting that causes N+1 query issues.

Enable CORS correctly for your front-end domains

too permissive is a security risk.

Publish Content Fragment Models, endpoint configuration, persisted queries, fragments, and referenced assets as one release checklist.

Set explicit cache-control expectations per persisted query so product listings, legal notices, and news feeds do not share the same freshness policy.

Version or deprecate persisted queries carefully; front-end apps may depend on field names and response shape.

🏛️ Architect's Note

Senior Architect's Perspective

GraphQL is the future of AEM content delivery. If you're designing a new AEM project, plan for headless from the start — even if you're not going headless today.

Key decision: REST vs GraphQL? For AEM, GraphQL is preferred for Content Fragment delivery because it matches the fragment model naturally. Use REST APIs for DAM operations (asset upload, metadata update).

For AEM as a Cloud Service: The GraphQL endpoint is production-ready and Adobe is investing heavily in it. The Content Fragment Editor and Model editor in AEMaaCS are significantly improved over AEM 6.5.

💬 Frequently Asked Questions

Can I use GraphQL subscriptions with AEM?

No. AEM's GraphQL implementation supports queries only — no mutations or subscriptions. For real-time content updates, use webhooks or polling patterns on the client side.

What is the fastest way to troubleshoot a broken headless page?

Call the persisted query URL directly, confirm the endpoint is published, verify every referenced fragment and asset is published, check Dispatcher filters, then inspect CORS and cache headers from the browser network tab.

🎯 Key Takeaways

1AEM GraphQL = read-only API for Content Fragment delivery
2Content Fragment Models automatically define the GraphQL schema
3Always use persisted queries in production — they're cacheable
4Enables headless delivery to React, mobile, and any HTTP client
5CORS configuration required for browser-based clients

🎯 Practice this topic in interviews

↗ Where this topic fits

Sources

Sources / References

Use these AEM references to verify the concept in official docs and continue into the most relevant SplashRide pages.

Related SplashRide pages

SplashRide AEM learning path

Browse the full AEM topic collection and learning order on SplashRide.

AEM Interview Prep

Practice AEM interview questions and scenario-based answers.

AEM Developer Career Path

This AEM developer career path explains how to become an AEM developer through JCR, Sling, HTL, client libraries, Dispatcher, Cloud Service delivery, project depth, and interview-ready enterprise implementation skills.

Drupal Developer Career Path

A practical route through Drupal content modeling, site building, theming, modules, configuration management, APIs, performance, deployment discipline, and interview preparation.

Content Fragments

Learn what Content Fragments are, how they differ from regular page content, and why they're the foundation of headless AEM delivery.

AEM as a Cloud Service

Understand what AEM as a Cloud Service is, how it differs from AEM 6.5, and what you need to know to develop and deploy on the cloud platform.