GraphQL Content Delivery overview
OverviewLink copied!
The GraphQL Content Delivery API is designed to optimize content delivery by providing the tools to eliminate under fetching and over fetching, allowing you to find the exact content you want and return only the content you need.
With its support for complex experience management, the GraphQL Content Delivery API brings flexibility and efficiency to the process of retrieving content. Developers can retrieve specific content, using less requests, less data and less bandwidth, to deliver enhanced experiences for end users.
The Amplience GraphQL Content Delivery API also provides the following benefits:
- Experiences that are optimized for speed and scalability due to the underlying NoSQL architecture of the Amplience CMS - Dynamic content.
- Spending less time managing your GraphQL schema with automatic schema generation and publishing.
- Only publishing graphs if they are valid, preventing breaking changes from causing system downtime.
- Manual overrides are provided to give developers the freedom to define their own type names and to exclude unwanted content item types from their graphs.
Please note that all examples use the GraphQL examples hub, which can be accessed at the following URL: https://amplience-examples.cdn.content.amplience.net/graphql
Setting up your GraphQL environmentLink copied!
In order to use the GraphQL Content Delivery API, Content Delivery 2 must be enabled. If you want to use the GraphQL Content Delivery API but don’t have Content Delivery 2 enabled already, contact your Amplience Customer Success Manager.
Using the GraphQL API endpointLink copied!
An API endpoint exists for each hub, and this allows users to query the latest published graph for the corresponding hub.
Endpoints are created using the standard syntax:
For example, if a hub were named “amplience-examples”, the endpoint would be:
These are public endpoints and therefore do not require any form of authentication (i.e. credentials or tokens) to query them.
You can also find the endpoint for a hub from the hub properties in Settings -> Hub settings -> Properties.
You can also access unpublished content via a virtual staging environment (VSE), rather than the endpoint for published content.
GraphQL API playgroundLink copied!
As the graphs are generated using GraphQL, you may use any GraphQL playground of your choice. GraphQL playgrounds can be used with Amplience graphs by pointing your playground environment to the graph’s API endpoint.
You can also use the Amplience playground to explore your graphs. To access the playground, use the GraphQL API endpoint for your chosen hub as the URL. You can find the API endpoint by clicking properties in your hub settings drop-down.
The API endpoint is the last link on the Properties page. Just click the copy icon to the right of the link and paste it into your web browser. This will take you to your Amplience playground.
For more information about accessing your GraphQL API endpoint, navigate to the Using the GraphQL API endpoint section.
The Amplience playground contains all the content and data associated with the hub you've used the endpoint for. The maximum size of graph supported by the playground is 1 MB. If your generated graph exceeds this size it will still be possible to use the playground to query your graph, however features such as the documentation section will not work.
Make sure to use the endpoint associated with the hub you would like to query content from. If you have the wrong hub endpoint when creating a query, you will receive an error.
The Amplience playground has many in-built features to enhance your coding experience, some of which include:
- Switching between multiple tabs to view different code snippets
- The ability to prettify, copy and merge fragments into your queries
- A documentation explorer and history log of previous queries to reuse
- The ability to refetch GraphQL schemas and access a short-keys dialog for a more seamless coding experience
Upon first opening the Amplience GraphQL playground, you may come across an error similar to the one shown below.
This error appears when there is no schema associated with the hub you're working from. To solve this, create a schema for your chosen hub. Learn more about creating schemas here.
Examples: Trying out GraphQLLink copied!
Once you have setup your API Playground, you can try running a few simple GraphQL queries. As an example, let's try querying for the title, description and read time of the blog post content type below.
To query this blog post in a GraphQL playground, we need either the delivery key or the content id. In the example query below, we're using the delivery key.
As shown below, our query returns a GraphQL format result that includes the title of our blog post, the description and the read time:
Working with graphs in GraphQLLink copied!
GraphQL creation and publishingLink copied!
Dynamic content automatically creates and publishes a GraphQL schema, known as a graph, for each Content Delivery 2 enabled hub. Each graph can then be queried via a dedicated API endpoint.
The creation of a graph is initiated when any content type in a Content Delivery 2 enabled hub is registered, synchronized, archived or unarchived. See the syncing a content type with its schema page to learn more about syncing a content type with its schema.
All content types registered on the hub are included by default in the schema. This includes, content, slots and partials, and unregistered types referenced by other types.
Once the graph has been created, it will automatically be published and available to query via the API endpoint.
It typically takes around 5 minutes from initiation to having a published graph that can be queried.
Updating an existing graphLink copied!
Dynamic content automatically updates each hub’s API endpoint with the latest published version of the graph for that hub.
A new graph is created and published for a hub every time a content type in that hub is registered, synchronized, archived or unarchived.
Graph conversion and GraphQL type namesLink copied!
Graphs are created by converting all content type schema for a given hub into a single GraphQL schema, known as a graph. The translation from content type schema (JSON) to a single graph (GraphQL schema) is automatically done by Dynamic content.
This is a 2-step process. Step 1 is to resolve a content type schema name from the content type schema ID and step 2 is converting this name to a GraphQL type name.
Step 1: Resolving a content type schema nameLink copied!
Each content schema type uses a URI as a unique identifier, the schema ID. To reduce the complexity of GraphQL type names only part of the schema ID URI is used to define the content schema type name.
Specifically, the content schema type name is resolved from the last part of the URI path (i.e. after the last “/”), any file type extension names are then removed.
Some examples of this process are shown below:
content type schema ID | content type schema Name |
---|---|
https://example.com/Banner-1 | Banner-1 |
https://example2.com/Banner-1 | Banner-1 |
https://example.com/Banner.JSON | Banner |
https://example.com/Example/SS22/_banner | _banner |
Step 2: Converting content type schema name to GraphQL type nameLink copied!
A set of rules are applied to translate the content type schema name to a valid GraphQL type name, the rules are as follows.
Some examples of these rules being applied are shown below:
content type schema Name | GraphQL type name |
---|---|
Banner-1 | Banner1 |
Banner | Banner |
__banner | Banner |
1banner | _1banner |
Id-banner | IdBanner |
Query | _Query |
Using the all naming prefixLink copied!
When listing content in GraphQL, you will notice that your content type schema name will be prefixed with the word 'all'. This is because all of your content is listed under that specific content type, so if you would like to access or filter them, you would have to query using the 'All' prefix.
For example, if you have named your content type schema PdpContentBlock
, when listing all content within this content type, you will have to query for allPdpContentBlock
.
The example below shows how we would query for the category ID of the first three pieces of content within the PdpContentBlock
content type:
As shown below, our query returns a nested list of all the category IDs for the first three pieces of content within the PdpContentBlock
content type:
GraphQL type name collisionLink copied!
It is possible that the type name translation process may generate the same GraphQL type name for more than one content type schema, this collision leads to an invalid graph that cannot be published. The last valid graph will remain published at the API endpoint until the collision is resolved.
For more information about how to solve typename collisions, visit our GraphQL type name collision helper page, where you will learn how to use our helper to make the troubleshooting process a lot quicker.
The most common scenarios where a collision may occur are:
- A hub has multiple content schema types with the same name
- A hub has multiple content schema types where their names only differ by what separator type, they use.
For example: content type schema with an ID of https://example.com/content/banner
and https://example.com/slot/banner
would both lead to a GraphQL type name of Banner
.
If type name collisions do occur, manual intervention is required to resolve them before a new valid graph can be created and published for that hub. This can be done by either excluding content type schema from the graph or adding GraphQL type name overrides to content type schema.
If a graph fails to be created or updated as expected it is likely a name collision has occurred. Users should review the names of their content type schema to identify collisions and manually resolve them.
Excluding content type schema from a graphLink copied!
It is possible for users to manually exclude specific content type schema from a hub’s graph. This needs to be defined for each content type schema that is to be excluded.
The graphql:skip
directive can be used in a content type schema to identify if it should be excluded when building the hub’s graph. By default this directive is not included in content type schema.
The directive accepts only a boolean value. The following table describes the different configuration options for this:
Configuration | Result |
---|---|
Not included in content type schema (default behaviour) | content type schema included in graph |
graphql:skip : [any value other than true] | content type schema included in graph |
graphql:skip : true | content type schema is not included in graph |
The following is an example content type schema that has been configured to be excluded from the hub’s graph.
It is also possible to use the graphql:skip
directive to exclude specific properties from a graph. To set at the property level, simply include the directive you wish to exclude.
The following is an example of the directive being used at a property level:
GraphQL type name overridesLink copied!
The GraphQL Content Delivery API has been designed to automatically generate, update and publish graphs. As part of this design GraphQL type names are automatically defined by Dynamic Content.
However, as a developer you can manually define your own GraphQL type names for content type schema. Type name overrides can be defined on a content type schema using the graphql:typename
directive.
If a user includes this directive the value defined against it will be used to generate the GraphQL type name.
The user specified value is evaluated during graph creation to ensure the syntax is valid, the following rules are automatically applied to ensure a valid type name is created.
- Replace unsupportable chars & other separators (
., space, -
) with_
- Replace multiple leading underscores with a single underscore
- If name starts with digit, prefix with
_
- Prefix reserved names with
_
or__
The following example shows how the graphql:typename
directive could be used to specify a GraphQL type name of BannerSlot for a specific content type schema.
It should also be noted that when a content type schema is archived, this also archives the GraphQL schema.
It is also possible to use the graphql:typename
directive to exclude specific properties from a graph. To set at the property level, simply include the directive in the property you wish to exclude.
The following is an example of the directive being used at a property level:
Raw JSON Property HelperLink copied!
The underlying content model is made up of JSON content. A helper is provided as part of the GraphQL schema Delivery API to allow users to return the raw JSON for a given property as part of a GraphQL request.
To return the raw JSON for a property a user can use the GraphQL schema creationProperty(propertyName: $propertyname)
field, which is available for every GraphQL type.
A value needs to be passed into the rawProperty field in order to identify which property should have its raw JSON returned.The following example shows how this helper can be used to return the raw JSON for a given property, in this case the background
property:
The above query returns the below response, including data pertaining to the tutorialBanner content:
It is possible to return raw JSON for given properties alongside non-raw JSON in the same query. The following screenshot shows an example of this:
The above query gives us the following response, providing the raw JSON for our given properties alongside our non-raw JSON:
Raw JSON content item HelperLink copied!
The underlying content model is made up of JSON type.
A helper is provided as part of the GraphQL Content Delivery API to allow users to return the raw JSON for an entire content item as part of a GraphQL request.
To return the raw JSON for an entire content item a user can use the rawJson{content}
field, which is available for every GraphQL GraphQL. The following example shows how this helper can be used to return the raw JSON for a given property, in this case the background
property.
The above query gives us the following response:
It is possible to return raw JSON for a given content item alongside non-raw JSON in the same query. The following screenshot shows an example of this:
The above query gives us the following response, providing the raw JSON for our given properties alongside our non-raw JSON:
Filter by content type queriesLink copied!
It is possible to build GraphQL queries that filter for content from a given content type using the GraphQL Content Delivery API. Pagination is used alongside this functionality to manage the query responses. For more information about using filter in GraphQL, head to the GraphQL filter page.
In the below examples, listing, filter and sort queries are shown:
Example of list queryLink copied!
Return first two names in list of author names from author typeLink copied!
The above query gives us the following GraphQL response:
Example of filter queryLink copied!
Return the SKU ID of the first two PDP content blocks filtered by product familyLink copied!
This query returns the following response:
Example of list query using sortLink copied!
Return first three text posts sorted by date in descending orderLink copied!
This query returns the following response:
UsageLink copied!
MethodsLink copied!
The GraphQL Content Delivery API supports the POST
method. The query should be sent in the body of a POST
request. The body must be in JSON format and the query should be in the following format:
Status codesLink copied!
Status code | Description |
---|---|
200 | Request has returned data. If an error is generated alongside data a 200 will be returned. |
400 | Non-specific error with request, usually due to an invalid query. |
404 | schema not found. |
In the case of multiple error the status code of the highest x00
bracket will be returned. For example, if there is a 400
and 500
, then a 500
is returned.
Error response formatLink copied!
All error responses are generated in GraphQL format, as shown below:
The message
property is used to provide a description of the error that has
occurred, and this is formatted as a sentence. This property will always be provided in an error response.
The code
property is used to provide a corresponding error code for the
error that has occurred. This property will always be provided in an error response.
The reason
property provides additional context for why the error
occurred. This property is formatted as a code and will only be returned when additional information needs to be provided.
Below is an example error generated when the complexity limit is
exceeded. In this scenario, the reason
property is returned:
Below is an example error generated when the user provides both a
delivery id and a delivery key. In this scenario the reason
property is not returned:
Retrieving unpublished contentLink copied!
A virtual staging environment (VSE) can now be used in place of the production GraphQL Content Delivery URL to retrieve the latest version of content, rather than only published content.
A VSE is associated with the hub from which the content is retrieved and can be copied from the visualization or preview settings in the Dynamic Content app.
For example, the endpoint to retrieve unpublished content is in the Amplience Examples hub is:
Navigating to this URL in a browser will open the GraphQL playground. Any queries run in the playground will retrieve the latest version of the content.
Finding the default virtual staging environment for a hubLink copied!
The virtual staging environment can be accessed by navigating to visualization
in the settings of your hub in Dynamic Content.
You will find the URL for the default virtual staging environment associated with your hub here.
As shown in the screenshot above, the virtual staging environment for our Amplience Examples hub is:
https://1ur5144f984rq1ulolazdecvf8.staging.bigcontent.io
To access the GraphQL playground for your virtual staging environment, add /graphql
to the end of the URL for your hub's virtual staging environment. For example, the GraphQL VSE playground URL for the above hub would be:
https://1ur5144f984rq1ulolazdecvf8.staging.bigcontent.io/graphql
Using the playground with unpublished contentLink copied!
In the example below, we've updated a banner on the Amplience Examples hub, but not published the latest version.
The headline is updated from "Spice up your home with our homeware picks" to "Breathe new life into your living space with these items". This new headline change is saved, not republished.
A delivery preview visualization is shown on the right of the content form and and displays the updated, but not yet published, content.
Because you can retrieve the latest version of content, even if it's not yet published, you can develop your own visualizations using GraphQL.
When we query for all tutorial banners using allTutorialBanner
in the GraphQL VSE playground, it returns a response that includes our unpublished headline in the screenshot above.
Our query to request all tutorial banners goes as follows:
And this returns the following response:
VSE can also be used to retrieve unpublished content that has not been previously published at all.
LimitsLink copied!
Several different limits are enforced by the GraphQL Content Delivery API. This includes common request and response limits to prevent excessively large queries or queries that take a long time to run.
Also, the GraphQL Content Delivery API uses complexity scoring to mitigate the risk of extremely complex responses that would likely cause performance issues.
Rule | Limit | Notes | |
---|---|---|---|
Request size | 8KB | If a request exceeds this limit, the query will not be run and an error will be returned. | |
Response size | 1MB | If a request exceeds this limit, the query will not be run and an error will be returned. | |
Depth limit | 22 | Dynamic content provides the ability to nest content items, the ability to nest is restricted to a depth of 22. | |
Response timeout | 10 seconds | The response timeout limit for a query is 10 seconds. If a query has not completed within this time, the query will be ended, and an error will be returned. | |
GraphQL schema size | 1MB | If a GraphQL schema exceeds this limit, it will not be possible to run an introspection query | |
Complexity score | 1000 | A score of 1 point is assigned to every item that is returned by a query, the Complexity score is set at 1000. If a query's score exceeds this limit (i.e. more than 1000 items returned), the query will be ended, and an error will be returned. |
Examples - with complexity scoreLink copied!
Single content item queryLink copied!
The following query shown in the screenshot below has a score of 1 as it only returns content from a single content item.
The above query produces the following response:
Multiple content item queryLink copied!
The following query has a score of 3 as it returns content from three content items with no linked content.
The above query produces the following response:
Multiple content item query with linked contentLink copied!
The following query has a score of 3 as it returns content from two content items and one of these content items includes linked content.
The above query produces the following response:
NotesLink copied!
We'll be adding several features in forthcoming releases, including:
- Returning entire hierarchies
- Field level localization