服务端 API:内容类型(Content-types)

页面摘要: 服务端 API 从服务端入口文件导出一个 contentTypes 对象来声明插件内容类型。推荐的命名约定是让导出键与 info.singularName 使用相同的值,这样在查询或清理数据时运行时 UID 才能保持可预测。

一个插件可以通过从 服务端入口文件 导出 contentTypes 对象来声明自己的内容类型。Strapi 在启动时将这些内容类型注册到插件命名空间下,并通过文档服务 API 和内容类型注册表使它们可用。

WARNING

在深入阅读本页概念之前,请确保你已经:

声明

contentTypes 导出是一个对象,其中每个键都在插件命名空间下注册一个内容类型。为避免混淆,该键应与 schema 中的 info.singularName 字段保持一致。其值是一个带有指向 schema 定义的 schema 属性的对象。

JavaScript

'use strict';

const article = require('./article');

module.exports = {
  // highlight-next-line
  article: { schema: article }, // recommended: keep key aligned with info.singularName
};
{
  "kind": "collectionType",
  "collectionName": "my_plugin_articles",
  "info": {
    // highlight-next-line
    "singularName": "article",
    "pluralName": "articles",
    "displayName": "Article"
  },
  "options": {
    "draftAndPublish": false
  },
  "attributes": {
    "title": {
      "type": "string",
      "required": true
    },
    "body": {
      "type": "richtext"
    }
  }
}

TypeScript

import article from './article';

export default {
  // highlight-next-line
  article: { schema: article }, // recommended: keep key aligned with info.singularName
};
{
  "kind": "collectionType",
  "collectionName": "my_plugin_articles",
  "info": {
    // highlight-next-line
    "singularName": "article",
    "pluralName": "articles",
    "displayName": "Article"
  },
  "options": {
    "draftAndPublish": false
  },
  "attributes": {
    "title": {
      "type": "string",
      "required": true
    },
    "body": {
      "type": "richtext"
    }
  }
}

UIDs 与命名约定

当一个插件内容类型被注册时,Strapi 会从插件命名空间和 contentTypes 导出中使用的键构建其运行时 UID:

plugin::<plugin-name>.<content-types-key>

推荐的约定是设置 content-types-key === info.singularName。遵循此约定可使 schema 命名与运行时 UID 保持一致,且更易阅读。

当键与 singularName 匹配时(推荐),生成的 UID 遵循以下格式:

plugin::<plugin-name>.<singular-name>

例如,一个名为 my-plugin 的插件,其内容类型的 singularName 为 article、导出键为 article,其 UID 为 plugin::my-plugin.article。

WARNING

如果 contentTypes 键与 info.singularName 不一致,getters 和查询会使用从注册键(而非 singularName)构建的 UID。这可能会在插件代码中引入命名不一致。

此 UID 在所有 API 中一致使用:

Use caseExample
通过文档服务查询strapi.documents('plugin::my-plugin.article').findMany()
通过 getter 访问 schemastrapi.contentType('plugin::my-plugin.article')
在路由处理程序中引用handler: 'article.find'(简写形式,通过插件注册表解析)
传递给清理 APIstrapi.contentAPI.sanitize.output(data, schema, { auth })
NOTE

控制器、服务、策略和中间件在全局 getters 中使用相同的 plugin::<plugin-name>.<resource-name> UID 格式,但在插件级 API(如路由 handler 和 policies)中通过简写注册表键(例如 'article')引用。详见 Getters & usage。

运行时访问

使用文档服务 API 查询

使用文档服务 API 从控制器、服务或生命周期 hook 中查询插件内容类型:

JavaScript

module.exports = ({ strapi }) => ({
  async findAll(params = {}) {
    // highlight-next-line
    return strapi.documents('plugin::my-plugin.article').findMany(params);
  },

  async create(data) {
    return strapi.documents('plugin::my-plugin.article').create({ data });
  },
});

TypeScript

import type { Core } from '@strapi/strapi';

export default ({ strapi }: { strapi: Core.Strapi }) => ({
  async findAll(params: Record<string, unknown> = {}) {
    // highlight-next-line
    return strapi.documents('plugin::my-plugin.article').findMany(params);
  },

  async create(data: Record<string, unknown>) {
    return strapi.documents('plugin::my-plugin.article').create({ data });
  },
});
文档服务 API

有关可用方法和参数的完整列表,请参阅 文档服务 API。

访问 schema

使用内容类型 getter 来检索 schema 对象,例如将其传递给清理 API:

JavaScript

const schema = strapi.contentType('plugin::my-plugin.article');

const sanitizedOutput = await strapi.contentAPI.sanitize.output(
  data,
  schema,
  { auth: ctx.state.auth }
);

TypeScript

const schema = strapi.contentType('plugin::my-plugin.article');

const sanitizedOutput = await strapi.contentAPI.sanitize.output(
  data,
  schema,
  { auth: ctx.state.auth }
);

最佳实践

  • 让导出键与 info.singularName 完全一致。 这可保持命名可读且一致。在运行时,Strapi 从插件命名空间下 contentTypes 映射的键派生插件内容类型 UID。即便注册仍然成功,不匹配也可能产生令人困惑的 UID 和维护问题。

  • 使用 collectionName 以避免表名冲突。 collectionName 字段设置数据库表名。用插件名作为前缀(例如 my_plugin_articles)以避免与应用内容类型或其他插件发生名称冲突。

  • 将内容类型 schema 保存在各自的文件中。 在每个 schema 定义在以其 singularName 命名的子文件夹内的专用 schema.json 文件中(例如 content-types/article/schema.json)。这匹配 Plugin SDK 生成的结构,并使 index 文件保持可读。

  • 仅在需要时启用 draftAndPublish。 草稿与发布会为内容类型添加发布工作流。仅当插件的用例需要时才启用它,因为它会增加查询和内容管理的复杂性。