Skip to main content

The GraphQL API has been updated

In Strapi 5, the GraphQL API has been updated. It handles the new, flattened response format (see related breaking change), and can also now accept Relay-style queries.

Flat queries still return a simple array of documents. You can also use Relay-style *_connection queries, which return nodes and a pageInfo object to handle pagination. Use these when you need metadata about pages or total counts.

This page is part of the breaking changes database and provides information about the breaking change and additional instructions to migrate from Strapi v4 to Strapi 5.

 Is this breaking change affecting plugins?Yes
 Is this breaking change automatically handled by a codemod?No

List of changes

TopicDescription of the changes
File upload support
  • Removed uploadFile uploadFiles mutations
  • Removed updateFileInfo mutation in favor of using the updateUploadFile mutation
  • Removed removeFile mutation in favor of using the deleteUploadFile mutation
  • Removed folder queries & mutations
  • Removed createUploadFile mutation
Internationalization supportRemoved the createXXLocalization mutations in favor of being able to update any locale from the main updateXXX mutation
Draft & Publish supportRemoved publicationState in favor of status to align with the new Draft & Publish behavior
Schema changes
  • Simplified the basic queries with no meta/pagination
  • Introduced Connection to add pagination

For an extensive description of the new Strapi 5 GraphQL API, please refer to the GraphQL API reference documentation.

Migration

To gradually convert to the new GraphQL API format, follow these steps:

  1. Enable the v4CompatibilityMode retro-compatibility header so queries can continue to rely on data.attributes.* while you refactor clients. Configure it in config/plugins.{js,ts}. With the flag on, the server keeps returning the Strapi v4 shape.

    config/plugins.js
    module.exports = {
    graphql: {
    config: {
    v4CompatibilityMode: true,
    },
    },
    };
    {
    restaurants {
    data {
    id
    attributes {
    title
    image {
    data {
    id
    attributes {
    url
    }
    }
    }
    images {
    data {
    id
    attributes {
    url
    }
    }
    }
    xToOneRelation {
    data {
    id
    attributes {
    field
    }
    }
    }
    xToManyRelation {
    data {
    id
    attributes {
    field
    }
    }
    }
    }
    }
    meta {
    pagination {
    page
    pageSize
    }
    }
    }
    }
  2. Adopt documentId which replaces numeric id in GraphQL. Update queries and mutations to read and send documentId, even while compatibility mode is on.

    {
    restaurants {
    data {
    documentId
    attributes {
    title
    image {
    data {
    documentId
    attributes {
    url
    }
    }
    }
    images {
    data {
    documentId
    attributes {
    url
    }
    }
    }
    xToOneRelation {
    data {
    documentId
    attributes {
    field
    }
    }
    }
    xToManyRelation {
    data {
    documentId
    attributes {
    field
    }
    }
    }
    }
    }
    }
    }
    mutation UpdateRestaurant {
    updateRestaurant(
    documentId: "some-doc-id",
    data: { title: "My great restaurant" }
    ) {
    data {
    documentId
    attributes {
    title
    image {
    data {
    documentId
    attributes {
    url
    }
    }
    }
    }
    }
    }
    }
  3. Rename collection fields with their _connection variants. This unlocks Relay pagination metadata while still keeping the v4-style data and attributes shape.

    {
    # collection fields can be renamed to _connection to get a v4 compat response
    restaurants_connection {
    data {
    id
    attributes {
    title
    image {
    data {
    id
    attributes {
    url
    }
    }
    }
    # collection fields can be renamed to _connection to get a v4 compat response
    images_connection {
    data {
    id
    attributes {
    url
    }
    }
    }
    xToOneRelation {
    data {
    id
    attributes {
    field
    }
    }
    }
    # collection fields can be renamed to _connection to get a v4 compat response
    xToManyRelation_connection {
    data {
    id
    attributes {
    field
    }
    }
    }
    }
    }
    meta {
    pagination {
    page
    pageSize
    }
    }
    }
    }
  4. Once collection and single queries use *_connection, stop wrapping user fields in attributes. This applies to queries and mutation responses.

    {
    # collection fields can be renamed to _connection to get a v4 compat response
    restaurants_connection {
    data {
    id
    title
    image {
    data {
    id
    url
    }
    }
    # collection fields can be renamed to _connection to get a v4 compat response
    images_connection {
    data {
    id
    url
    }
    }
    xToOneRelation {
    data {
    id
    field
    }
    }
    # collection fields can be renamed to _connection to get a v4 compat response
    xToManyRelation_connection {
    data {
    id
    field
    }
    }
    }
    meta {
    pagination {
    page
    pageSize
    }
    }
    }
    }
  5. (Optional) If you need Relay-compliant pagination, rename data to nodes and meta.pagination to pageInfo. When a client does not need pagination metadata, you can also drop _connection entirely.

    {
    # Rename data to nodes & meta.pagination to pageInfo
    restaurants_connection {
    nodes {
    id
    title
    image {
    id
    url
    }
    images_connection {
    nodes {
    id
    url
    }
    }
    xToOneRelation {
    id
    field
    }
    xToManyRelation_connection {
    nodes {
    id
    field
    }
    }
    }
    pageInfo {
    page
    pageSize
    }
    }
    }
    {
    # remove _connection & data if you don't need pagination att all
    restaurants {
    id
    title
    image {
    id
    url
    }
    images {
    id
    url
    }
    xToOneRelation {
    id
    field
    }
    xToManyRelation {
    id
    field
    }
    }
    }
  6. Disable the v4CompatibilityMode compatibility header so the server emits the Strapi 5 format natively.