3文档

Core · 开发应用

应用开发概览

认识应用代码、模板和插件的关系,理解一个业务功能如何连接页面、接口、服务与数据库。

开发一个 NocoBase 应用,就是在已有的应用结构和能力上实现业务规则:数据怎样保存,谁可以执行操作,页面怎样把结果呈现给用户。本节按主题介绍这些工作,供你开发时查阅;如果想先从头完成一个功能,可以阅读搭建第一个应用。

以下使用独立的“项目与任务”示例说明各部分职责。它与入门示例的表名、接口和测试配置不同;运行专题代码前,先按数据模型与迁移准备对应版本。只了解职责时,不必先运行示例。

应用代码、模板和插件

创建应用后,你得到的是一份可以修改和独立维护的应用源码。模板提供初始结构,Core 的包提供运行与开发能力,插件提供可复用的功能。

部分 提供什么 开发时怎样使用
应用代码 自己的页面、接口、数据模型、业务服务和测试 在应用仓库中直接修改,随应用发布
应用模板 启动入口、页面布局、组件、配置和开发约定 创建时生成到项目中;以后升级时合并模板变化
Core 的基础包 客户端和服务端运行时、数据访问、配置等 通过公开 API 使用,由项目依赖管理版本
插件 认证、用户、权限、文件等可复用能力 使用应用已注册插件的公开接口、组件和扩展方式

例如,项目名称和任务归属是应用自己的业务;登录和角色权限可以使用已有插件。默认模板已经带有多种插件,开发功能时先检查现有能力,无需把“安装插件”当作每个功能的第一步。

任务页面也不必包装成插件。只有需要在多个应用之间复用、独立发布和管理版本时,才需要考虑插件边界。不要修改 node_modules/ 中的插件实现来定制应用。

模板生成的布局和主题同样属于应用源码。优先使用路由声明、组件组合和主题配置;确实需要改动框架结构时,记录原因,方便以后升级 NocoBase Core时保留业务定制。

一个功能由哪些部分组成

以“把任务归入项目”为例,完整交付不只有一个选择框:

部分 要解决的问题 示例中的位置
数据模型 任务怎样保存项目,旧任务怎样保留,项目不存在时怎么办 database/main/migrations/
业务服务 能否修改这条任务,目标项目是否可选,怎样保存关联 server/providers/tutorial-project-service.ts
HTTP 接口 谁在调用,输入是否合法,返回什么结果 server/routes/tutorial-projects.ts
权限声明与服务注册 有哪些业务操作,服务怎样供接口使用 server/providers/tutorial-projects.ts
页面路由与导航 从哪里进入,哪些用户可以打开页面 client/routes.ts
页面与交互 展示当前项目,选择候选项,处理加载和保存结果 client/pages/tasks/[taskId]/project.tsx
文案 中英文名称、字段提示和错误反馈 client/locales/
验证 数据是否保留,允许的操作能否成功,越权是否被拒绝 tests/

这些位置是一份分工表,不是每次都要新增一套文件。只调整表单文案不需要迁移,只增加字段也不必重新编写登录模块。先找出需求改变了什么,再修改对应部分。完整目录说明见项目结构。

一次保存怎样到达数据库

用户在“修改项目”弹窗中选好项目并点击保存后,请求沿着下面的路径处理:

  1. 页面收集输入。 页面通过 useApiClient() 请求 PATCH tutorialTasks/:id/project,提交项目 ID;解除关联则提交 null。客户端使用相对于应用 API 根路径的地址,不写死服务器地址或 /main。
  2. 接口处理请求边界。 路由验证登录状态、修改归属的操作权限、任务 ID 和请求内容,并取得本次操作在任务与项目两边的数据权限策略。
  3. 服务执行业务规则。 接口调用 TutorialProjectService.assignTask()。服务通过带策略的 Repository 查找任务和目标项目,确认允许操作后更新关联;本例把这些数据库操作放在同一事务中。
  4. 数据库保存结果。 迁移已经建立字段和外键,数据库拒绝指向不存在项目的关联。迁移负责事先改变结构,不会在每次保存时重新运行。
  5. 结果返回页面。 接口返回保存结果,页面更新任务列表并给出反馈。失败时保留用户输入,把字段错误放回选择框;任务已经不存在时停止编辑。

服务处理业务规则,Provider 负责把服务注册到应用容器中,两者不是同一个概念。接口通过服务 token 取得服务实例,服务本身不依赖页面,也不需要读取 HTTP Context。以后有其他调用入口时,可以复用业务规则,但仍要明确该入口的身份、权限和输入校验。

权限贯穿整条路径

页面访问权限决定能否进入页面;业务操作权限决定能否执行动作;数据范围决定这次操作可以处理哪些记录。隐藏按钮只是界面反馈,不能替代服务端检查。

“修改任务项目”尤其需要检查两边:用户既要能修改这条任务,也要能把任务分配到目标项目。能查看项目不代表能进行分配。外键只能证明项目存在,不能证明当前用户有权使用它。

文件需要接入应用

新建文件后,还要通过应用已有入口注册:

  • client/routes.ts 声明页面及导航;页面组件放在 client/pages/。
  • server/routes/index.ts 收集应用接口。
  • server/providers/index.ts 收集服务 Provider。
  • client/runtime.ts 和 server/runtime.ts 组合各自的路由、插件、配置和服务。

通常添加业务功能只需要修改这些收集入口,不需要改写客户端或服务端的启动流程。不要把“文件已经存在”当作“功能已经注册”。

怎样拆分一次业务改动

先用业务语言写清楚结果。例如:“用户可以把一条任务归入自己有权选择的项目,旧任务保留原样,保存失败时不丢失输入。”再依次回答:

  1. 数据如何演进? 新字段是否允许为空,旧数据如何处理,哪些规则需要数据库约束。
  2. 操作如何授权? 谁能打开页面、调用接口,各自可以处理哪些任务和项目。
  3. 接口如何表达? 输入、输出、失败情况是什么,哪些业务规则需要复用。
  4. 页面如何反馈? 加载、空结果、无权限、保存成功和失败时分别展示什么。
  5. 怎样验证? 在独立测试数据上验证正常路径、拒绝路径和原有功能。

这份顺序也适用于和 Agent 合作。业务决定由你提供,项目约定和具体实现可以交给 Agent 查阅、实现和验证,见和 Agent 一起开发。

按当前问题继续阅读

当前要处理的问题 文档
给现有数据增加字段、关系或约束 数据模型与迁移
校验请求、复用业务规则、检查权限并声明 API 业务服务与 HTTP 接口
实现列表、表单、弹窗及加载和错误反馈 UI 组件与交互
编写数据查询、批量操作与事务 查询与操作数据
组织页面、菜单与访问条件 页面、路由与导航
配置运行参数与业务管理入口 应用配置与系统设置
调整语言和应用外观 多语言与主题
查看、更新或扩展已注册能力 管理插件
选择验证方式并完成验收 测试与验收
想先跑通一个完整功能 搭建第一个应用

专题文章使用同一个项目示例说明约定,便于相互对照。阅读时可以直接进入需要的主题;运行其中的代码时,按该篇的示例前提准备相应模型、接口和权限。

NocoBase 3 文档 · 草稿 2026-10-24