不建议使用文档服务 API 更新可重复组件
页面摘要: 在 Strapi 5 中,文档的草稿版本和已发布版本使用不同的数字组件
id。重用已发布响应中的id来更新草稿通常会失败。在出现稳定的组件标识之前,建议替换完整的组件数组(或针对草稿 id 进行编辑)。
在 Strapi 5 中,不建议通过重用已发布 API 响应中的组件 id 来更新可重复组件,原因在于草稿与发布功能与文档服务 API 的交互方式。
本页面是破坏性变更数据库的一部分,提供有关该破坏性变更的信息,以及从 Strapi v4 迁移到 Strapi 5 的附加说明。
破坏性变更说明
在 Strapi v4 中
你可以通过传入数字 id 来部分更新可重复组件。
在 Strapi 5 中
文档使用稳定的 documentId,但嵌套组件仍使用与状态相关的数字 id。发布操作会创建新的组件行,因此同一区块的草稿版本和已发布版本具有不同的 id。你不能将已发布的组件 id 当作文档级标识符对待。
迁移
本节汇总了关于该破坏性变更的有用说明和操作步骤。
说明
启用草稿与发布后,典型的内容 API 流程如下:
// 请求:内容 API 默认返回已发布版本
GET /api/articles
// 响应(已发布)
{
data: {
documentId: '…',
components: [
{ id: 2, name: 'component-1' },
{ id: 4, name: 'component-2' },
],
},
}
使用那些已发布的 id 进行更新会写入草稿,而草稿具有不同的组件行 id:
PUT /api/articles/{documentId}
{
data: {
components: [
{ id: 2, name: 'component-1-updated' }, // 已发布 id,对草稿通常无效
],
},
}
这通常失败并出现类似 Some of the provided components in components are not related to the entity 的错误,因为 id: 2 并未链接到草稿条目。这与 REST API 响应中组件和动态区域不再返回 id 这一变更有关。
文档服务 在读取/更新时默认针对草稿,因此当你使用草稿组件 id 时,按 id 进行原地更新可以生效(在内容管理器中也一样)。陷阱在于将已发布 id 与草稿写入混用。
推荐的变通方案
在出现稳定的嵌套标识之前,请使用以下方案之一。
1. 替换完整的组件数组(内容 API 推荐)
省略组件 id 并发送完整的期望列表。Strapi 会在草稿上重新创建这些组件。这是面向 REST/GraphQL 客户端(它们只看到已发布数据)的受支持且不易出错的方案:
// 文档服务
await strapi.documents('api::article.article').update({
documentId,
data: {
components: [
{ name: 'component-1-updated' },
{ name: 'component-2' },
],
},
});
// REST 内容 API
PUT /api/articles/{documentId}
{
"data": {
"components": [
{ "name": "component-1-updated" },
{ "name": "component-2" }
]
}
}
包含所有希望保留的组件。数组中省略的条目会从草稿中移除。
2. 针对草稿组件 id 进行编辑(文档服务 / 管理面板风格)
如果你控制后端(自定义路由、脚本、文档服务),先加载草稿,再使用这些 id 进行更新:
const draft = await strapi.documents('api::article.article').findOne({
documentId,
status: 'draft',
populate: ['components'],
});
await strapi.documents('api::article.article').update({
documentId,
data: {
components: draft.components.map((component) =>
component.id === targetDraftId
? { id: component.id, name: 'component-1-updated' }
: { id: component.id, name: component.name }
),
},
});
不要在此模式下重用默认内容 API GET(已发布)返回的 id。
3. 禁用草稿与发布
如果在内容类型上禁用了草稿与发布,则只有一组组件行,因此基于 id 的更新问题较少。但为了客户端代码更简单,仍建议优先使用完整数组替换模式。