Skip to main content

v4 代码迁移:更新服务

¥v4 code migration: Updating services

本指南是 v4 代码迁移指南 的一部分,旨在帮助你将 Strapi 应用的代码从 v3.6.x 迁移到 v4.0.x

¥This guide is part of the v4 code migration guide designed to help you migrate the code of a Strapi application from v3.6.x to v4.0.x

🤓 v3/v4 比较

在 Strapi v3 和 v4 中,创建内容类型会自动生成核心 API 服务。服务是一组可重用的功能。

¥In both Strapi v3 and v4, creating content-types automatically generates core API services. Services are a set of reusable functions.

在 Strapi v3 中,服务导出一个对象,其中包含与核心 API 服务的现有操作合并的操作,从而允许自定义。

¥In Strapi v3, services export an object containing actions that are merged with the existing actions of core API services, allowing customization.

在 Strapi v4 中,服务将调用结果导出到 createCoreService 工厂功能,无论是否进一步定制。

¥In Strapi v4, services export the result of a call to the createCoreService factory function, with or without further customization.

service 迁移到 Strapi v4 包括确保它使用 v4 中引入的 createCoreService 工厂功能。

¥Migrating a service to Strapi v4 consists in making sure it uses the createCoreService factory function introduced in v4.

由于 Strapi v3 和 v4 中的服务实现之间存在差异,建议创建一个新的服务文件,然后选择将现有的 v3 自定义项引入新文件并在必要时进行调整。

¥Due to the differences between services implementation in Strapi v3 and v4, it's recommended to create a new service file, then optionally bring existing v3 customizations into the new file and adapt them when necessary.

✏️ 注意

可以使用 交互式 CLI 命令 strapi generate.conf 自动创建服务文件。

¥The service file can be created automatically with the interactive CLI command strapi generate.

创建 Strapi v4 服务:

¥To create a Strapi v4 service:

  1. ./src 文件夹内创建 api/<api-name>/services/<service-name>.js 文件(请参阅 项目结构)。

    ¥Create a api/<api-name>/services/<service-name>.js file inside the ./src folder (see project structure).

  2. 将以下代码复制并粘贴到 ./src/api/<api-name>/services/<service-name>.js 文件的顶部。该代码从 Strapi 核心包含的工厂导入 createCoreService 工厂函数:

    ¥Copy and paste the following code at the top of the ./src/api/<api-name>/services/<service-name>.js file. The code imports the createCoreService factory function from the factories included with the core of Strapi:

    const { createCoreService } = require('@strapi/strapi').factories;
  3. 复制并粘贴以下代码,将 api-namecontent-type-name 替换为适当的名称。该代码导出对 createCoreService 工厂函数的调用结果,并将内容类型的唯一标识符(例如 api::api-name.content-type-name)作为参数传递:

    ¥Copy and paste the following code, replacing api-name and content-type-name with appropriate names. The code exports the result of a call to the createCoreService factory function, passing the unique identifier of the content-type (e.g. api::api-name.content-type-name) as an argument:

    module.exports = createCoreService('api::api-name.content-type-name')
  4. (可选)要自定义服务,请将第二个参数传递给 createCoreService 工厂函数。该参数可以是一个对象,也可以是一个返回对象的函数。该对象包含方法,这些方法可以是全新的操作,也可以替换或扩展核心 API 控制器的现有操作(参见 服务实现文档)。

    ¥(optional) To customize the service, pass a second argument to the createCoreService factory function. This argument can be either an object or a function returning an object. The object contains methods, which can either be entirely new actions or replace or extend existing actions of core API controllers (see services implementation documentation).

Example of a v4 service without customization:
./src/api/<content-type-name>/services/<service-name>.js

const { createCoreService } = require('@strapi/strapi').factories;

module.exports = createCoreService('api::api-name.content-type-name');
Example of a v4 service with customization:
./src/api/<content-type-name>/services/<service-name>.js

const { createCoreService } = require('@strapi/strapi').factories;

module.exports = createCoreService('api::api-name.content-type-name', ({ strapi }) => ({
async find(...args) {
const { results, pagination } = await super.find(...args);

results.forEach(result => {
result.counter = 1;
});

return { results, pagination };
},
}));

💡 定制技巧
  • 可以使用 super(例如 super.find())调用原始服务的 CRUD 方法。

    ¥The original service’s CRUD methods can be called using super (e.g. super.find()).

  • this.getFetchParams() 实用函数可用于将参数与一些默认参数(例如 publicationState 的默认值)封装起来。this.getFetchParams() 具有以下签名:(params: Object) => Object

    ¥The this.getFetchParams() utility function can be used to wrap parameters with some default parameters (e.g. a default value for the publicationState). this.getFetchParams() has the following signature: (params: Object) => Object.

更多示例可以在 服务实现文档 中找到。

¥More examples can be found in the services implementation documentation.

🤓 下一步

Strapi 的 迁移后端代码 到 v4 还需要至少迁移 Strapi 服务器的核心功能,例如 configurationdependenciesroutescontrollers内容类型模式

¥Migrating the backend code of Strapi to v4 also requires to at least migrate the core features of the Strapi server, such as the configuration, dependencies, routes, controllers, and content-type schemas.