GraphQL API
The GraphQL API allows performing queries and mutations to interact with the content-types through Strapi's GraphQL plugin. Results can be filtered, sorted and paginated.
To use the GraphQL API, install the GraphQL plugin:
- Yarn
- NPM
yarn add @strapi/plugin-graphql
npm install @strapi/plugin-graphql
Once installed, the GraphQL playground is accessible at the /graphql
URL and can be used to interactively build your queries and mutations and read documentation tailored to your content-types:
The GraphQL API does not support media upload. Use the REST API POST /upload
endpoint for all file uploads and use the returned info to link to it in content types. You can still update or delete uploaded files with the updateUploadFile
and deleteUploadFile
mutations using media files id
(see mutations on media files).
Queries
Queries in GraphQL are used to fetch data without modifying it.
When a content-type is added to your project, 2 automatically generated GraphQL queries are added to your schema, named after the content-type's singular and plural API IDs, as in the following example:
Content-type display name | Singular API ID | Plural API ID |
---|---|---|
Restaurant | restaurant | restaurants |
Singular API ID vs. Plural API ID:
Singular API ID and Plural API ID values are defined when creating a content-type in the Content-Type Builder, and can be found while editing a content-type in the admin panel (see User Guide). You can define custom API IDs while creating the content-type, but these can not modified afterwards.
Fetch a single document
Documents can be fetched by their documentId
.
{
restaurant(documentId: "a1b2c3d4e5d6f7g8h9i0jkl") {
name
description
}
}
Fetch multiple documents
To fetch multiple documents you can use simple, flat queries or Relay-style queries:
- Flat queries
- Relay-style queries
To fetch multiple documents you can use flat queries like the following:
restaurants {
documentId
title
}
Relay-style queries can be used to fetch multiple documents and return meta information:
{
restaurants_connection {
nodes {
documentId
name
}
pageInfo {
pageSize
page
pageCount
total
}
}
}
Fetch relations
You can ask to include relation data in your flat queries or in your Relay-style queries:
- Flat queries
- Relay-style queries
The following example fetches all documents from the "Restaurant" content-type, and for each of them, also returns some fields for the many-to-many relation with the "Category" content-type:
{
restaurants {
documentId
name
description
# categories is a many-to-many relation
categories {
documentId
name
}
}
}
The following example fetches all documents from the "Restaurant" content-type using a Relay-style query, and for each restaurant, also returns some fields for the many-to-many relation with the "Category" content-type:
{
restaurants_connection {
nodes {
documentId
name
description
# categories is a many-to-many relation
categories_connection {
nodes {
documentId
name
}
}
}
pageInfo {
page
pageCount
pageSize
total
}
}
}
For now, pageInfo
only works for documents at the first level. Future implementations of Strapi might implement pageInfo
for relations.
Possible use cases for pageInfo
:
This works:
{
restaurants_connection {
nodes {
documentId
name
description
# many-to-many relation
categories_connection {
nodes {
documentId
name
}
}
}
pageInfo {
page
pageCount
pageSize
total
}
}
}
This does not work:
{
restaurants_connection {
nodes {
documentId
name
description
# many-to-many relation
categories_connection {
nodes {
documentId
name
}
# not supported
pageInfo {
page
pageCount
pageSize
total
}
}
}
pageInfo {
page
pageCount
pageSize
total
}
}
}}
Fetch media fields
Media fields content is fetched just like other attributes.
The following example fetches the url
attribute value for each cover
media field attached to each document from the "Restaurants" content-type:
{
restaurants {
images {
documentId
url
}
}
}
For multiple media fields, you can use flat queries or Relay-style queries:
- Flat queries
- Relay-style queries
The following example fetches some attributes from the images
multiple media field found in the "Restaurant" content-type:
{
restaurants {
images_connection {
nodes {
documentId
url
}
}
}
}
The following example fetches some attributes from the images
multiple media field found in the "Restaurant" content-type using a Relay-style query:
{
restaurants {
images_connection {
nodes {
documentId
url
}
}
}
}
For now, pageInfo
only works for documents. Future implementations of Strapi might implement pageInfo
for the media fields _connection
too.
Fetch components
Components content is fetched just like other attributes.
The following example fetches the label
, start_date
, and end_date
attributes values for each closingPeriod
component added to each document from the "Restaurants" content-type:
{
restaurants {
closingPeriod {
label
start_date
end_date
}
}
}
Fetch dynamic zone data
Dynamic zones are union types in GraphQL so you need to use fragments (i.e., with ...on
) to query the fields, passing the component name (with the ComponentCategoryComponentname
syntax) to __typename
:
The following example fetches data for the label
attribute of a "Closingperiod" component from the "Default" components category that can be added to the "dz" dynamic zone:
{
restaurants {
dz {
__typename
...on ComponentDefaultClosingperiod {
# define which attributes to return for the component
label
}
}
}
}
Fetch draft or published versions
If the Draft & Publish feature is enabled for the content-type, you can add a status
parameter to queries to fetch draft or published versions of documents :
query Query($status: PublicationStatus) {
restaurants(status: DRAFT) {
documentId
name
publishedAt # should return null
}
}
query Query($status: PublicationStatus) {
restaurants(status: PUBLISHED) {
documentId
name
publishedAt
}
}
Mutations
Mutations in GraphQL are used to modify data (e.g. create, update, and delete data).
When a content-type is added to your project, 3 automatically generated GraphQL mutations to create, update, and delete documents are added to your schema.
For instance, for a "Restaurant" content-type, the following mutations are generated:
Use case | Singular API ID |
---|---|
Create a new "Restaurant" document | createRestaurant |
Update an existing "Restaurant" restaurant | updateRestaurant |
Delete an existing "Restaurant" restaurant | deleteRestaurant |
Create a new document
When creating new documents, the data
argument will have an associated input type that is specific to your content-type.
For instance, if your Strapi project contains the "Restaurant" content-type, you will have the following:
Mutation | Argument | Input type |
---|---|---|
createRestaurant | data | RestaurantInput! |
The following example creates a new document for the "Restaurant" content-type and returns its name
and documentId
:
mutation CreateRestaurant($data: RestaurantInput!) {
createRestaurant(data: {
name: "Pizzeria Arrivederci"
}) {
name
documentId
}
}
When creating a new document, a documentId
is automatically generated.
The implementation of the mutations also supports relational attributes. For example, you can create a new "Category" and attach many "Restaurants" (using their documentId
) to it by writing your query like follows:
mutation CreateCategory {
createCategory(data: {
Name: "Italian Food"
restaurants: ["a1b2c3d4e5d6f7g8h9i0jkl", "bf97tfdumkcc8ptahkng4puo"]
}) {
documentId
Name
restaurants {
documentId
name
}
}
}
If the Internationalization (i18n) feature is enabled for your content-type, you can create a document for a specific locale (see i18n documentation).
Update an existing document
When updating an existing document , pass the documentId
and the data
object containing new content. The data
argument will have an associated input type that is specific to your content-type.
For instance, if your Strapi project contains the "Restaurant" content-type, you will have the following:
Mutation | Argument | Input type |
---|---|---|
updateRestaurant | data | RestaurantInput! |
For instance, the following example updates an existing document from the "Restaurants" content-type and give it a new name:
mutation UpdateRestaurant($documentId: ID!, $data: RestaurantInput!) {
updateRestaurant(
documentId: "bf97tfdumkcc8ptahkng4puo",
data: { name: "Pizzeria Amore" }
) {
documentId
name
}
}
If the Internationalization (i18n) feature is enabled for your content-type, you can create a document for a specific locale (see i18n documentation).