Skip to main content

实体服务 API 到文档服务 API 迁移参考

🌐 Entity Service API to Document Service API migration reference

在 Strapi 5 中,文档服务 API 替代了 Strapi v4 的实体服务 API(见 重大更改说明)。

🌐 In Strapi 5, the Document Service API replaces the Entity Service API from Strapi v4 (see breaking change description).

本页面旨在向开发者说明如何从实体服务 API 迁移,通过描述哪些自定义代码的更改将由 升级工具 的代码修改(codemods)处理,以及哪些将需要手动处理。

🌐 The present page is intended to give developers an idea of how to migrate away from the Entity Service API, by describing which changes in custom code will be handled by codemods from the upgrade tool and which will have to be handled manually.

使用升级工具进行迁移

🌐 Migration using the upgrade tool

在使用 升级工具 时,会运行一个代码修改工具(codemod),并处理 entityService 迁移的某些部分。

🌐 When using the upgrade tool, a codemod is run and handles some parts of the entityService migration.

Caution

该 codemod 只更改函数调用和一些参数。这不能被视为完整的迁移,因为 codemod 永远无法将 entityId 转换为 documentId

🌐 The codemod is only changing the function calls and some parameters. This can not be considered as a complete migration as the codemod will never be able to convert an entityId into a documentId.

Codemod 范围

🌐 Codemod scope

以下列表解释了 codemod 自动处理的内容(✅)、codemod 未处理的内容且必须 100% 手动处理的内容(❌)以及 codemod 运行后仍需要手动干预的内容(🚧):

🌐 The following list explains what is automatically handled by the codemod (✅), what is not handled by the codemod and must be handled 100% manually (❌) and what will still require manual intervention after the codemod has run (🚧):

主题由 codemod 处理?需要手动执行的步骤
代码结构✅ 是没有。
代码结构已自动迁移。
publicationState 已移除,取而代之的是 status✅ 是没有。
代码修改工具会自动进行转换。
使用 documentId 代替 Strapi v4 的唯一标识符🚧 部分完成:
  • codemod 会向你的代码中添加新的 documentId 属性,因为 documentId 是在 Strapi 5 中需要使用的新唯一标识符。
  • 但实际的 documentId 值无法被推测,所以在 codemod 运行后,你会在代码中发现 __TODO__ 占位符值。
👉 __TODO__ 占位符值需要手动更新。

例如,你可能会将
documentId: "__TODO__"
改为类似
documentId: "ln1gkzs6ojl9d707xn6v86mw" 的值。
更新 published_at 以触发发布❌ 未处理.
👉 请更新你的代码,改为使用文档服务 API 的新 publish()unpublish()discardDraft() 方法。

函数调用迁移的示例

🌐 Examples of function calls migration

以下示例显示了升级工具中的 codemod 如何更新各种函数调用的代码。

🌐 The following examples show how the codemod from the upgrade tool updates the code for various function calls.

findOne

之前:

strapi.entityService.findOne(uid, entityId);


之后:

strapi.documents(uid).findOne({
documentId: "__TODO__"
});

findMany

之前:

strapi.entityService.findMany(uid, {
fields: ["id", "name", "description"],
populate: ["author", "comments"],
publicationState: "preview",
});

之后:

strapi.documents(uid).findMany({
fields: ["id", "name", "description"],
populate: ["author", "comments"],
status: "draft",
});

create

之前:

strapi.entityService.create(uid, {
data: {
name: "John Doe",
age: 30,
},
});

之后:

strapi.documents(uid).create({
data: {
name: "John Doe",
age: 30,
},
});

update

之前:

strapi.entityService.update(uid, entityId, {
data: {
name: "John Doe",
age: 30,
}
});

之后:

strapi.documents(uid).update({
documentId: "__TODO__",
data: {
name: "John Doe",
age: 30,
}
});

delete

之前:

strapi.entityService.delete(uid, entityId);


之后:

strapi.documents(uid).delete({
documentId: "__TODO__"
});

count

之前:

strapi.entityService.count(uid);

之后:

strapi.documents(uid).count();

手动迁移

🌐 Manual migration

  • 希望手动迁移的用户可以通过复制 codemod 所做的操作来进行迁移(参考 codemod 范围函数调用示例)。

  • 在代码中使用实体服务(Entity Service)装饰器的插件开发者必须将其替换为文档服务(Document Service)中间件。下面的示例可以让你了解它们的工作原理,更多信息可以在专门的 文档服务中间件文档 中找到:

    在 Strapi v4 中:

    strapi.entityService.decorate((service) => {

    return Object.assign(service, {

    findOne(entityId, params = {}) {
    // e.g., exclude soft deleted content
    params.filters = { ...params.filters, deletedAt: { $notNull: true } }
    return service.findOne(entityId, params)
    }
    });
    })

    在 Strapi 5 中

    strapi.documents.use((ctx, next) => {
    if (ctx.uid !== "api::my-content-type.my-content-type") {
    return next();
    }

    if (ctx.action === 'findOne') {
    // customization
    ctx.params.filters = { ...params.filters, deletedAt: { $notNull: true } }
    const res = await next();
    // do something with the response if you want
    return res;
    }

    return next();
    });
  • 根据以下情况,更新你在单一类型上的 findMany() 自定义代码:
    • 在 Strapi v4 中,当在单一类型上调用 findMany() 函数时,它会返回单个项目。
    • 在 Strapi 5 中,findMany() 函数是通用的,并且总是返回数组,无论是对单一类型还是集合类型调用。要通过 findMany() 调用获取单一类型的数据,请从返回的数组中提取第一个项目。