有没有编写可以对数据库进行 CRUD 的简单 Strapi 插件的示例?

are there any examples of writing simple Strapi plugin that can CRUD to the database?

背景

我已经决定将 Strapi 作为我的项目的无头 CMS/backend 部署,并且对开箱即用的设置感到非常满意。然而,我的项目的一部分需要通过一个简单的表单来捕获用户输入,我认为通过编写自定义插件和利用相同的后端来扩展 Strapi 的 REST API 是一种方式,而不是用自己的方式启动另一个快速服务器D B。我能够找到关于生成插件的文档,并且我很好地理解了不同插件文件的文件结构和逻辑如何工作(模型、控制器、策略、配置、路由等...)。然而,在我的一生中,我无法找到最基本的资源或任何足够的文档来说明如何编写逻辑允许我的控制器挂钩到 Strapi 为我的自定义创建的基本 CRUD 方法 collection ('messages' 在我的例子中)。

到目前为止我做了什么

     {   "routes": 
       [
        {
         "method": "POST",
         "path": "/postMessage",
         "handler": "contact-form.postMessage"
        }
       ]
     }
     {
     "kind": "collectionType",
     "connection": "default",
     "info": {
       "name": "message",
       "description": "This represents the Message Model"
      },
     "attributes": {
       "name": {
         "default": "",
         "type": "string",
         "required": true
        },
       "email": {
         "default": "",
         "type": "email",
         "required": true
        },
       "message": {
         "default": "",
         "type": "text",
         "required": true
        }
     }
    }

开发服务器重新启动后,Strapi 已经识别出我的插件并在其数据库中反映了 'message' 模型,我可以从管理面板正确看到 collection。

我需要什么帮助

我想做的是扩展插件的 REST API 端点,以提供与 Strapi 在创建新 collection/entity 时构建的开箱即用端点相同的功能,同时向其添加自定义业务逻辑层。

如果有人能给我指出一个示例或资源,以显示 Strapi 向插件公开的方法或函数,可以挂钩或调用这些插件来实现这一点,我将不胜感激。


[更新] 6 月 14 日

因此,经过数小时的记录和检查 Strapi 向控制器公开的 object 的 10 秒后,我发现 strapi object 公开了一个 query 方法接受 2 个参数,第一个是 model,第二个是 plugin 名称。简单来说,以下内容使我能够对我的 collection:

执行写入操作
postMessage: async (ctx) => {
  const testData = {
    name: 'John Doe',
    email: 'john@doe.com',
    message: 'Hello World!'
  }

  result = await strapi.query("message","contact-form").create(data)
}

但是,我仍然不认为这是一个答案,因为我想找到一种可以使用内置策略和服务的更全面的方法。此外,我仍然不确定调用此方法是否会绕过 Strapi 为默认控制器设置的任何中间件层,从而使应用程序面临安全或稳定性风险。

以上内容可以通过使用内置 Strapi entityService 公开的方法来实现。通过检查堆栈如何通过自动构建的 API 端点处理创建操作,我能够将 entityService 识别为该功能的适当模块。但是,当将插件的型号名称传递给 strapi.entityService.create({data} , {model: 'modelName') 时,服务无法找到 modelName。所以我检查了该服务的源代码,发现它接受的是模型 UID。所以在自定义插件的情况下,我们需要传递格式如下的 modelUID 而不是仅仅传递 modelName

plugins::plugin-name.modelName

总而言之,对于针对我问题中示例的创建操作,情况如下:

const result = await strapi.entityService.create(
  { data: ctx.request.body },
  { model: "plugins::contact-form.message" }
)

Strapi 支持的所有其他 CRUD 操作也由 entityService 公开,并且可以以类似的方式访问(创建、更新、查找、FindOne 等...)。您可以在 Strapi 文档 > 概念 > 控制器 > 核心控制器下找到所有这些方法。

我还创建了一个 YouTube 视频来介绍其工作原理: https://www.youtube.com/watch?v=kIZHzbmnhnU