GraphQL filter
The GraphQL API lets you list, sort and filter your content. You can choose the sort order of your results and filter content using one or more custom properties.
On this page we'll explain how to use the GraphQL filter functionality, including how to list, sort and filter content. We will provide examples for how to perform each of these actions. Alongside the examples we have also provided a number of schema examples and code snippets so that you can try them out on your own hub.
You can try out any of the examples on this page, or your own queries, on our Amplience examples playground
NamingLink copied!
The name you give your content type schema is what will be used to query your content in GraphQL. This is because the graphs in GraphQL are created by converting all content type schemas for a given hub into a single GraphQL schema, known as a graph. For example, if you were to create a new content type schema and use the name 'blog post' at the end of the URI path (i.e. after the last “/”), your content type schema would be known as 'BlogPost' in GraphQL.
At the same time, a GraphQL query is created to allow users to filter by content type. The GraphQL types created to be used for filter by type queries prefix the single GraphQL type name with “all” and camelCase the single GraphQL type name.
Some examples below:
content type schema name | GraphQL name | GraphQL Filter name |
---|---|---|
author | author | allAuthor |
BlogPost | blogpost | allBlogPost |
Media | media | allMedia |
For more examples and information about the naming process, click here.
GraphQL argumentsLink copied!
ArgumentsLink copied!
Filter by content type queries support four different arguments to be passed in, these are:
Argument name | Description |
---|---|
first | Show the first [n] results, user defines [n]. |
last | Show the last [n] results, user defines [n]. |
before | Passes a cursor as a string and is combined with either the “first” or “last” argument to return the first/last [n] results before the given cursor. |
after | Passes a cursor as a variable and is combined with either the “first” or “last” argument to return the first/last [n] results after the given cursor) |
A filter by type query requires either the “First” or “Last” argument to be defined in order for the query to be valid. “First” and “Before” also can not be used together. Similarly, “Last” and “After” can not be used together.
FieldsLink copied!
Filter by content type queries support 2 different fields, these are:
Argument name | Description |
---|---|
edge | This field is used to specify which fields to return for each content item of that type. Further details of how to use this field are described below. |
pageInfo | This field is used to return pagination information. |
EdgeLink copied!
The edge
field is used to specify which fields to return for each content
item of that type. The “edge” field is made up of two further fields, see below:
Argument name | Description |
---|---|
cursor | This field is used to return a cursor for each content item for the given content type. |
node | This field is used to specify fields from the content item to return. This field contains all fields the corresponding single GraphQL type contains. |
Page InfoLink copied!
The “pageInfo” field is used to return pagination information. The “pageInfo” field is made up of four further fields, see below:
Argument name | Description |
---|---|
endCursor | When specified returns the End Cursor for the results page. |
hasPreviousPage | When specified returns a Boolean response indicating if the current page has a previous page. |
hasNextPage | When specified returns a Boolean response indicating if the current page has a next page |
startCursor | When specified returns the Start Cursor for the results page. |
PaginationLink copied!
GraphQL filter uses the cursor connections specification to allow pagination of results. With pagination, a maximum of 50 results is returned for each page. You can specify the page size in the filter request. If you don't specify the page size, the maximum number of 50 items will be returned.
In the following example the page size is set to 1 using the first
argument, which gives us our response in a descending manner. In this case, the first content item will be returned per page in the response.
Alternatively, if we wanted the last item from our content, we would use the last
argument and set this to 1.
In the next example the page size is set to the first 3, so a maximum of 3 content items will be returned per page in the response.
Due to the maximum page size being 50, we cannot set the page size to more than this number. If we do, an error will be given that tells us the correct number of items that can be shown per page. In the screenshot below, we have set the page size to 100 using the first
argument. In response, we have received an error informing us that the max page size is 50.
If you would like to know whether your paginated content has a next or previous page, you would use the hasNextPage
or hasPreviousPage
argument, which would return a boolean result. For example, below we are checking to see whether our paginated list of author names would have a next page if we set the page size to 2.
This gives us the following result, which shows us that our content indeed does have another page of results for us to query for:
To query for the next page of content, we will need to fetch the endCursor
and startCursor
. An example of an endCursor
query follows the below format:
This gives us the endCursor
as a response:
We can then use this endCursor
string to query for last results of the next page of results. To do this we would include the endCursor
string in our query while using the before
argument:
Alternatively, we can include the startCursor
string in our query while using the after
argument to query for the first results, as shown below.
To get the startCursor
, we would query for it in the same way we query for the endCursor
.
For more information about pagination and limits, read the API limits page.
Listing contentLink copied!
If you want to list content for a given content type you can use the all[GraphQL name]
typename. For example, if you have a content type schema called BlogPost
, you would use the allBlogPost
GraphQL typename to list all pieces of content for that Content Type. Alternatively, if you want to return a single piece of content by a specific delivery ID or Key, you would then query by BlogPost
without the all
prefix.
In the example shown below we are querying for the titles and descriptions of all content created by the blog content type schema. To do this we use the edge
and node
field within our query:
All blog titles and descriptions created using this schema will be returned in the response:
More list examplesLink copied!
These examples demonstrate how to use the first and last arguments when listing content in GraphQL. In this instance, we are listing the names of authors from the author content type.
Return first two names in list of author names from author typeLink copied!
The above query gives us the following GraphQL response:
Return last two items in list of author names from author typeLink copied!
The above query gives us the following GraphQL response:
For more information on how the first and last arguments work, refer to Pagination.
Filtering contentLink copied!
You can filter on other string, number or boolean properties defined in your content type schema. For example, you could return all products with a category of "mens suits" or all blogs with the category of "homeware". Filters can be combined, so you can filter on products with a category of "ties" that are in the "Silk" product family, or all blogs in a particular category with a read time of 10.
The filterable traitLink copied!
If you want to filter on any other properties then these properties must be defined in a trait:filterable
object in the content type schema.
The trait includes a filterBy
array that includes the path for each property that you will use to filter your content. Path entries are specified in JSON Pointer format and can be string, number or boolean types. The filterBy
array can contain up to 5 paths, not including the schema id which is included automatically.
Before defining a path to be filtered on, a graphql:filtername
must be given using standard camel case. This must be followed by the filterBy
array which will be used to make a request to the filter API to retrieve content with properties of the specified value.
In the example we are using the category
property as a filter.
Note that you can only include properties defined in the schema itself and not in any linked content.
Filtering using multiple propertiesLink copied!
Filters can be combined, so you could request all products that have a categoryId of "mens-accessories-ties" and a product family of "Silk". To combine filters you need to define a path containing both filters. In the example shown below the productFamily
and categoryId
properties are combined:
Up to 5 entries can be included in a single path.
Specifying filter in your GraphQL queryLink copied!
To filter content using one of the paths defined in your filterBy
array, include the schema, the graphql:filtername
and the path in your GraphQL query. In the example shown below, we're requesting the categoryID and SKU numbers of all content created by the PDP content block content type that has a product family of "Womenswear". Note that you always need to include the schema in the request.
This query returns the following response:
If you want to query for content while filtering on multiple properties, you would need to first specify the paths you would like to filter on within the content type schema, and give that path a graphql:filtername
.
For example, if we wanted to filter on both product family and category ID for a particular Pdp content block, we would first specify the paths in our content type schema and give it a graphql:filtername
of byProductFamilyAndCategory
, written in camel case. When querying for the content later, we would simply specify the graphql:filtername
in our filter field and detail both the particular product family and category ID we're searching for.
The following code snippet shows what this query would look like if we were searching for the SKU id and meta info for all Pdp Content Blocks with the product family "Womenswear" and the category id "grey-jacket":
This query returns the following response:
Sorting contentLink copied!
By default content will be returned sorted by date created, but you can specify your own sort order. For example, a list of blog posts could be sorted by read time or ranking.
To define a sort option you need to include a trait:sortable
object in you content type schema containing the sort key, graphql:sortname
and the path to one or more properties used to sort the content. It should be noted that if you choose to use a default sort key, you do not need to specify the graphql:sortname
.
The sort traitLink copied!
The trait:sortable
object is added at the top level of the schema and can contain up to 3 sort paths, one of which must have the "default" key.
The trait includes a sortBy
array that includes the path for each property that you will use to for your content. Path entries are specified in JSON pointer format and can be string, number or boolean types.
The trait:sortable
object shown below includes a default sort key that is used to sort blog content using the readTime
property. Due to this being the default sort key, we do not need to specify the graphql:sortname
.
You can specify multiple entries in a sort path, up to a maximum of 5.
In the example below we have specified two sort keys: "default" and "readTime".
The default sort key will sort the content by date
and ranking
. If the blog post date of two items is the same, then the ranking
will be used as a tie breaker.
The "readTime" sort key will sort the content by readTime
followed by date
and then if those properties are both equal, "ranking" will be used.
The use of a graphql:sortname
is encouraged, but if one is not included, there will be an attempt to infer the sort name from the key field. If the inferred name causes a naming collision with another sort name, it will prevent the generation of a schema. In this case, a unique graphql:sortname
would have to be specified.
When creating a sort name, make sure to use standard camel case naming conventions - ie. byTime
, byDate
, byRanking
.
Using a duplicate graphql:sortname
or graphql:filtername
will cause a schema to not be generated until the conflict is resolved by a unique graphql:sortname
or graphql:filtername
being specified.
Specifying sort in your GraphQL queryLink copied!
If you have included a trait:sortable
object in your content type schema, then if you don't specify a sort in your GraphQL filter query, the content will be sorted using your default sort and in ascending order.
To specify a sort, include a sortBy
object in your query. In the example shown below, we're requesting the titles of all items created by our blog content type and sorted in descending order by readTime
, followed by date
and then ranking
. If you don't specify a sort order, then ascending order will be used.
If you do not include a sort trait in your schema, the content will be sorted by date created.
This gives us the following JSON format response:
Other notesLink copied!
- The default and maximum page size is 50.
- The request timeout is 10 seconds. If this time is exceeded the request will return a 524 error
- There is a complexity limit of 1000 items. This refers to the number of content items involved in processing a request. If the limit is exceeded, a 524 error is returned.
- If you request filter paths that are not included in your content type schema then the request will not return an error and instead 0 items will be returned.
Example schemasLink copied!
The example requests on this page use two schemas:
Blog post filter and sort. This is an update to the blog post schema used in our search examples. It has been modified to support filtering and sorting. It's included in the schema examples and also on its own page.
Product details. This is a product details schema that has multiple filterable properties. It's also included in the schema examples and also on its own page.