diff --git a/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated.md b/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated.md index 4217e91a5b..f4a8d68f60 100644 --- a/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated.md +++ b/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated.md @@ -37,306 +37,304 @@ For an extensive description of the new Strapi 5 GraphQL API, please refer to th To gradually convert to the new GraphQL API format, follow these steps: -1. Enable v4 compatibility mode with the `v4CompatibilityMode` flag in the configuration of the GraphQL plugin (see [plugins configuration](/cms/plugins/graphql#code-based-configuration)): +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. - ```graphql - { - restaurants { - data { - id - attributes { - title - image { - data { - id - attributes { - url - } - } - } - images { - data { - id - attributes { - url - } - } - } - xToOneRelation { - data { - id - attributes { - - } - } - xToManyRelation { - data { - id - attributes { - field - } - } - } - } - } - meta { - pagination { - page - pageSize - } - } - } - } - ``` + ```js title="config/plugins.js" + module.exports = { + graphql: { + config: { + v4CompatibilityMode: true, + }, + }, + }; + ``` -2. Use `documentId` instead of `id` for contentType queries & mutations: + ```graphql + { + 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 + } + } + } + } + ``` - Strapi 5 introduces [`documentId` as the main identifier](/cms/migration/v4-to-v5/breaking-changes/use-document-id) for documents, ensuring uniqueness across databases. The numeric `id` is still returned by the REST API for backward compatibility but is not available in GraphQL. +2. Adopt [`documentId`](/cms/migration/v4-to-v5/breaking-changes/use-document-id) which replaces numeric `id` in GraphQL. Update queries and mutations to read and send `documentId`, even while compatibility mode is on. - ```graphql - { - restaurants { - data { - documentId - attributes { - title - image { - data { - documentId - attributes { - url - } - } - } - images { - data { - documentId - attributes { - url - } - } - } - xToOneRelation { - data { - documentId - attributes { - - } - } - xToManyRelation { - data { - documentId - attributes { - field - } - } - } - } - } - meta { - pagination { - page - pageSize - } - } - } - } - ``` + ```graphql + { + 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 + } + } + } + } + } + } + } + ``` - ```graphql - { - mutation { - updateRestaurant( - documentId: "some-doc-id", - data: { title: "My great restaurant" } - ) { - data { - documentId - attributes { - title - image { - data { - documentId - attributes { - url - } - } - } - } - } - } - } - } - ``` + ```graphql + mutation UpdateRestaurant { + updateRestaurant( + documentId: "some-doc-id", + data: { title: "My great restaurant" } + ) { + data { + documentId + attributes { + title + image { + data { + documentId + attributes { + url + } + } + } + } + } + } + } + ``` -3. Move to `_connection` without changing response format (only applies to queries): +3. Rename collection fields with their `_connection` variants. This unlocks Relay pagination metadata while still keeping the v4-style `data` and `attributes` shape. - ```graphql - { - # 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 - } - } - } - } - ``` + ```graphql + { + # 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. Remove attributes (applies to queries & mutation responses): +4. Once collection and single queries use `*_connection`, stop wrapping user fields in `attributes`. This applies to queries and mutation responses. - ```graphql - { - # 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 - } - } - } - } - ``` + ```graphql + { + # 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. Use new naming or the simpler queries: +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. - ```graphql - { - # Rename data to nodes & meta.pagination to pageInfo - restaurants_connection { - nodes { - id - title - # can remove data in single Images - image { - id - url - } - # collection fields can be renamed to _connection to get a v4 compat response - images_connection { - nodes { - id - url - } - } - # can remove data in xToOne - xToOneRelation { - id - field - } - # collection fields can be renamed to _connection to get a v4 compat response - xToManyRelation_connection { - nodes { - id - field - } - } - } - pageInfo { - page - pageSize - } - } - } - ``` + ```graphql + { + # 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 + } + } + } + ``` - ```graphql - { - # remove _connection & data if you don't need pagination att all - restaurants { - id - title - image { - id - url - } - # remove _connection & data - images { - id - url - } - xToOneRelation { - id - field - } - # remove _connection & data - xToManyRelation { - id - field - } - } - } - ``` + ```graphql + { + # 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. diff --git a/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/new-response-format.md b/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/new-response-format.md index 8457fd940a..7b58f8a6a5 100644 --- a/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/new-response-format.md +++ b/docusaurus/docs/cms/migration/v4-to-v5/breaking-changes/new-response-format.md @@ -98,7 +98,48 @@ The Content API returns attributes of requested content without wrapping them in ### Notes -To use the Strapi v4 response format, set the following header: `Strapi-Response-Format: v4`. +The `Strapi-Response-Format: v4` header temporarily restores the Strapi v4 wrapping (`data.attributes.*`). You can keep the header in place while you update each consumer, then remove it once every client can read the flattened format. The header affects REST calls, including population on relations, but does not roll back the introduction of [`documentId`](/cms/migration/v4-to-v5/breaking-changes/use-document-id). + +To use the compatibility header while migrating: + +1. Capture a few baseline responses before you switch the header on. These samples help you compare payloads once `attributes` comes back and ensure that relations, components, and nested populations all respond as expected. +2. Add the `Strapi-Response-Format: v4` header to every REST request made by legacy clients. Remove it only after you have updated and tested each endpoint. +3. Keep in mind that `documentId` continues to be the only identifier returned by the REST API when the header is absent. With the header enabled, REST responses include both `id` (for backward compatibility) and `documentId` (the canonical identifier). Plan to migrate any downstream systems that still depend on numeric `id`. + +
+Examples +```bash title="curl" +curl \ + -H 'Authorization: Bearer ' \ + -H 'Strapi-Response-Format: v4' \ + 'https://api.example.com/api/articles?populate=category' +``` + +```js title="fetch" +await fetch('https://api.example.com/api/articles', { + headers: { + Authorization: `Bearer ${token}`, + 'Strapi-Response-Format': 'v4', + }, +}); +``` + +```js title="Axios" +const client = axios.create({ + baseURL: 'https://api.example.com/api', + headers: { + Authorization: `Bearer ${token}`, + 'Strapi-Response-Format': 'v4', + }, +}); + +const articles = await client.get('/articles', { params: { populate: '*'} }); +``` +
+ +:::tip +If you need to keep a mix of formats running, enable the header for any routes that still rely on `attributes`, then gradually remove it per endpoint or per consumer once you finish testing. +::: ### Manual procedure diff --git a/docusaurus/docs/cms/migration/v4-to-v5/introduction-and-faq.md b/docusaurus/docs/cms/migration/v4-to-v5/introduction-and-faq.md index 4c45619e57..227cb55096 100644 --- a/docusaurus/docs/cms/migration/v4-to-v5/introduction-and-faq.md +++ b/docusaurus/docs/cms/migration/v4-to-v5/introduction-and-faq.md @@ -56,3 +56,15 @@ Strapi Cloud will deploy the updated code in Strapi 5 and will automatically run
+ +
+How do I keep the legacy attributes wrapper during the migration? + +- For REST clients, add the `Strapi-Response-Format: v4` header while you refactor your code. The [new response format breaking change](/cms/migration/v4-to-v5/breaking-changes/new-response-format#migration) shows where to add the header in `curl`, `fetch`, and Axios requests. +- For GraphQL clients, enable `v4CompatibilityMode` and follow the steps of the [GraphQL API migration documentation](/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated#migration) to gradually remove `attributes`. +- REST responses continue to expose both `id` (legacy) and [`documentId`](/cms/migration/v4-to-v5/breaking-changes/use-document-id) when the header is enabled. GraphQL never exposes numeric `id`, so update your queries to use `documentId` even before you turn compatibility mode off. + +Once every consumer reads the flattened format, remove the header so Strapi emits the Strapi 5 response shape by default. +
+ +
diff --git a/docusaurus/docs/cms/migration/v4-to-v5/step-by-step.md b/docusaurus/docs/cms/migration/v4-to-v5/step-by-step.md index 5a1d41dad9..2d7ec65c85 100644 --- a/docusaurus/docs/cms/migration/v4-to-v5/step-by-step.md +++ b/docusaurus/docs/cms/migration/v4-to-v5/step-by-step.md @@ -99,18 +99,21 @@ For each of them, read the indicated breaking change entry and check if some man Strapi 5 has updated both the REST and GraphQL APIs. -Follow the steps below and leverage retro-compatibility flags and guided migration resources to gradually update your code for Strapi 5. +Follow the steps below and leverage retro-compatibility headers and guided migration resources to gradually update your code for Strapi 5. ### Migrate REST API calls -1. Enable the retro-compatibility flag by setting the `Strapi-Response-Format: v4` header. -2. Update your queries & mutations only, guided by the dedicated [breaking change entry for REST API](/cms/migration/v4-to-v5/breaking-changes/new-response-format). -3. Validate that your client is running correctly. -4. Disable the retro-compatibiliy flag by removing the `Strapi-Response-Format: v4` header and start using the new response format. +1. Enable the compatibility header everywhere you still expect `attributes`, by adding `Strapi-Response-Format: v4` to REST calls in HTTP clients, SDKs, and middleware (see the [breaking change entry](/cms/migration/v4-to-v5/breaking-changes/new-response-format#migration) for concrete examples). +2. While the header is on, audit existing payloads. Capture representative responses (including populated relations, components, and media) so you can verify that legacy consumers keep working during the transition. +3. Update and test each client by: + - removing `data.attributes` access, + - switching to the flattened payload, + - and adopting [`documentId`](/cms/migration/v4-to-v5/breaking-changes/use-document-id) wherever the REST API was previously returning numeric `id` only. +4. Disable the compatibility header per endpoint or consumer: once tests pass for a given client, remove `Strapi-Response-Format: v4` from its requests. Repeat until no consumer depends on the legacy wrapper. ### Migrate GraphQL API calls -1. Enable the retro-compatibility flag by setting `v4CompatibilityMode` to `true` in the `graphql.config` object of [the `/config/plugins.js|ts` file](/cms/plugins/graphql#code-based-configuration). -2. Update your queries and mutations only, guided by the dedicated [breaking change entry for GraphQL](/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated). -3. Validate that your client is running correctly. -4. Disable the retro-compatibily flag by setting `v4CompatibilityMode` to `false` and start using the new response format. +1. Enable the compatibility header by setting `v4CompatibilityMode` to `true` in the `graphql` plugin configuration, so clients can continue to rely on `data.attributes` while you refactor them. +2. Follow each step of the [breaking change entry for GraphQL](/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated). This will guide you to swap `id` for `documentId`, adopt `_connection` queries, remove `attributes`, and finally switch to `nodes/pageInfo`. +3. Test Relay and non-Relay queries by confirming that pagination metadata still matches expectations when you remove `_connection` and `data` for clients that do not need Relay semantics. +4. Disable the `v4CompatibilityMode` compatibility header: after every query and mutation works with the flattened schema, set the header to `false` so the server emits the Strapi 5 format by default. diff --git a/docusaurus/static/llms-full.txt b/docusaurus/static/llms-full.txt index b4e862576f..3dc30ec395 100644 --- a/docusaurus/static/llms-full.txt +++ b/docusaurus/static/llms-full.txt @@ -9244,6 +9244,18 @@ Strapi Cloud will deploy the updated code in Strapi 5 and will automatically run +
+How do I keep the legacy attributes wrapper during the migration? + +- For REST clients, add the `Strapi-Response-Format: v4` header while you refactor your code. The [new response format breaking change](/cms/migration/v4-to-v5/breaking-changes/new-response-format#use-the-compatibility-header-while-migrating) shows where to add the header in `curl`, `fetch`, and Axios requests. +- For GraphQL clients, enable `v4CompatibilityMode` and follow the steps of the [GraphQL API migration documentation](/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated#migration) to gradually remove `attributes`. +- REST responses continue to expose both `id` (legacy) and [`documentId`](/cms/migration/v4-to-v5/breaking-changes/use-document-id) when the header is enabled. GraphQL never exposes numeric `id`, so update your queries to use `documentId` even before you turn compatibility mode off. + +Once every consumer reads the flattened format, remove the header so Strapi emits the Strapi 5 response shape by default. +
+ +
+ # Step-by-step guide to upgrade to Strapi 5 @@ -9338,21 +9350,24 @@ For each of them, read the indicated breaking change entry and check if some man Strapi 5 has updated both the REST and GraphQL APIs. -Follow the steps below and leverage retro-compatibility flags and guided migration resources to gradually update your code for Strapi 5. +Follow the steps below and leverage retro-compatibility headers and guided migration resources to gradually update your code for Strapi 5. ### Migrate REST API calls -1. Enable the retro-compatibility flag by setting the `Strapi-Response-Format: v4` header. -2. Update your queries & mutations only, guided by the dedicated [breaking change entry for REST API](/cms/migration/v4-to-v5/breaking-changes/new-response-format). -3. Validate that your client is running correctly. -4. Disable the retro-compatibiliy flag by removing the `Strapi-Response-Format: v4` header and start using the new response format. +1. Enable the compatibility header everywhere you still expect `attributes`, by adding `Strapi-Response-Format: v4` to REST calls in HTTP clients, SDKs, and middleware (see the [breaking change entry](/cms/migration/v4-to-v5/breaking-changes/new-response-format#use-the-compatibility-header-while-migrating) for concrete examples). +2. While the header is on, audit existing payloads. Capture representative responses (including populated relations, components, and media) so you can verify that legacy consumers keep working during the transition. +3. Update and test each client by: + - removing `data.attributes` access, + - switching to the flattened payload, + - and adopting [`documentId`](/cms/migration/v4-to-v5/breaking-changes/use-document-id) wherever the REST API was previously returning numeric `id` only. +4. Disable the compatibility header per endpoint or consumer: once tests pass for a given client, remove `Strapi-Response-Format: v4` from its requests. Repeat until no consumer depends on the legacy wrapper. ### Migrate GraphQL API calls -1. Enable the retro-compatibility flag by setting `v4CompatibilityMode` to `true` in the `graphql.config` object of [the `/config/plugins.js|ts` file](/cms/plugins/graphql#code-based-configuration). -2. Update your queries and mutations only, guided by the dedicated [breaking change entry for GraphQL](/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated). -3. Validate that your client is running correctly. -4. Disable the retro-compatibily flag by setting `v4CompatibilityMode` to `false` and start using the new response format. +1. Enable the compatibility header by setting `v4CompatibilityMode` to `true` in the `graphql` plugin configuration, so clients can continue to rely on `data.attributes` while you refactor them. +2. Follow each step of the [breaking change entry for GraphQL](/cms/migration/v4-to-v5/breaking-changes/graphql-api-updated). This will guide you to swap `id` for `documentId`, adopt `_connection` queries, remove `attributes`, and finally switch to `nodes/pageInfo`. +3. Test Relay and non-Relay queries by confirming that pagination metadata still matches expectations when you remove `_connection` and `data` for clients that do not need Relay semantics. +4. Disable the `v4CompatibilityMode` compatibility header: after every query and mutation works with the flattened schema, set the header to `false` so the server emits the Strapi 5 format by default.