Prompt
How do I expose CMS content through GraphQL?
Latest observation
Oct 20, 2026
OpenAI APIWeb search: off
To expose CMS content through GraphQL, you typically add a GraphQL API layer on top of your CMS data model and then map CMS content types/entries into GraphQL types, queries, and resolvers.
High-level approach
-
Choose a GraphQL server/runtime
- Node.js: Apollo Server, Yoga, Mercurius
- .NET: Hot Chocolate
- Java: graphql-java / Spring GraphQL
- Python: Strawberry / Ariadne
-
Connect to your CMS
- If your CMS already has APIs, your GraphQL resolvers can call those APIs.
- If you control the database, resolvers can query the DB directly.
- If using a headless CMS, it may already provide GraphQL or plugin support.
-
Model CMS content as GraphQL types
- Example content types:
PagePostAuthorCategory
- Fields become GraphQL fields:
title,slug,body,publishedAt, etc.
- Example content types:
-
Implement queries
pageBySlug(slug: String!): Pageposts(limit: Int, offset: Int): [Post!]!author(id: ID!): Author
-
Write resolvers
- Resolvers fetch content from the CMS, transform it if necessary, and return the data GraphQL expects.
-
Handle relationships
- Example: a
Postcan have anauthorfield that resolves to anAuthor. - Use batching/caching to avoid N+1 query problems.
- Example: a
-
Add pagination, filtering, and auth
- Pagination: cursor-based or offset-based
- Filtering:
where,search,tags - Authorization: restrict draft/private content by user role
Example schema
type Query {
pageBySlug(slug: String!): Page
posts(limit: Int = 10, offset: Int = 0): [Post!]!
}
type Page {
id: ID!
title: String!
slug: String!
body: String!
}
type Post {
id: ID!
title: String!
slug: String!
excerpt: String
body: String!
author: Author
}
type Author {
id: ID!
name: String!
}
Example resolver flow
If your CMS stores posts in a database:
Query.postsruns a SQL query or ORM callPost.authorfetches the author byauthorId- You can use DataLoader to batch author lookups
Example in JavaScript (Apollo Server-style)
const resolvers = {
Query: {
posts: async (_, { limit, offset }, { db }) => {
return db.post.findMany({ take: limit, skip: offset });
},
pageBySlug: async (_, { slug }, { db }) => {
return db.page.findUnique({ where: { slug } });
}
},
Post: {
author: async (post, _, { db }) => {
return db.author.findUnique({ where: { id: post.authorId } });
}
}
};
If your CMS already supports GraphQL
Some CMS platforms provide GraphQL out of the box or via plugins, such as:
- Contentful
- Strapi
- Sanity
- Drupal
- WordPress (via WPGraphQL)
- Ghost (community packages / integrations)
In that case, you may not need to build a GraphQL layer from scratch — just configure it, define permissions, and query content directly.
Best practices
- Keep schema aligned with content model
- Use DataLoader or equivalent to avoid N+1 issues
- Support draft/published states cleanly
- Implement access control at resolver level
- Use pagination for large collections
- Avoid exposing raw internal CMS structure if not needed
- Add schema documentation and examples
Recommended architecture
Frontend → GraphQL API → CMS API/DB
This gives you:
- one API for clients
- flexible content queries
- the ability to aggregate multiple CMS/content sources
If you want, I can also show:
- a complete example using a specific CMS (WordPress, Strapi, Contentful, Sanity, etc.), or
- a step-by-step GraphQL implementation in Node.js, .NET, or Python.