Skip to content

架构设计与启动过程 ​

架构设计 ​

分层与模块化架构 ​

后端代码集中在 backend/app/ 下,整体分为三块:

  • api/:业务实现层,按子系统拆分为 module_system、module_infra、module_ai、module_bpm 四大模块,分别对应系统管理、基础设施、AI 大模型、BPM 工作流。
  • framework/:框架能力层,与具体业务无关,沉淀可复用的基础设施,如 database、web、security、common、file、websocket 等。
  • config/:配置层,集中管理环境配置、路径锚点和全局常量。

api/ 下所有业务模块统一挂载在版本前缀 v1 中,由顶层 main.py 聚合后通过 FastAPI 的 root_path(/api/v1)对外暴露。四大模块彼此独立,仅在需要时通过 framework 复用能力,避免业务耦合。

业务模块的分层文件职责 ​

每个业务域(如 user、role、dict)都是一个独立目录,内部遵循统一的分层约定,包含以下文件:

文件职责说明
controller.py路由与接口层定义 APIRouter、请求/响应模型绑定、权限声明,调用 service 并返回统一响应。
service.py业务逻辑层承载核心业务逻辑(校验、编排、跨表操作、导入导出等),调用 crud 完成数据访问。
crud.py数据访问层继承框架 CRUDBase,封装针对本模型的数据库增删改查与复杂查询。
model.py数据模型层定义 SQLAlchemy ORM 模型,借助 ModelMixin 等基类自动带出公共字段与元数据。
schema.py数据契约层定义 Pydantic 模型,用于请求体校验、响应序列化与查询参数声明。
__init__.py包标识维持包结构。

一次典型请求会从上往下穿过各层,再逐层返回:

这种分层让"接口定义、业务规则、数据操作"各司其职:新增功能时通常从 schema 定义契约,在 controller 声明路由,在 service 编写逻辑,必要时扩展 crud 与 model。

命名约定 ​

为保证可读性,项目在全链路使用一致的命名:

  • 模块目录:以 module_ 前缀区分子系统,如 module_system、module_ai。
  • 业务域目录:使用小写下划线,如 user、role、dict。
  • 类命名:每个分层文件内主类采用 领域 + 层 的命名,例如 UserRouter、UserService、UserCRUD、UserModel、UserOutSchema,便于在代码中通过类名即可判断其所属层。
  • 路由聚合:每个模块的 router.py 收集本模块下所有 controller 的路由,再以 APIRouter(prefix="/xxx") 挂载到顶层应用。

启动过程 ​

应用启动流程 ​

应用的入口是 backend/main.py,它基于 typer 提供命令行工具,核心命令有:

  • python main.py start --env dev:启动 FastAPI 服务(dev 环境自动开启热重载)。
  • python main.py revision --env dev:生成 Alembic 迁移脚本。
  • python main.py upgrade --env dev:执行数据库迁移到最新版本。

启动的关键在于:环境变量 ENVIRONMENT 必须在导入 settings 之前设置,以决定加载哪份环境配置。随后 create_app() 完成应用对象的构建:

启动后的生命周期(lifespan)由 app/app_init.py 管理,分为"启动期"与"关闭期"两段:

  • 启动期:依次加载全局事件(如建立 Redis 连接)、预热系统参数缓存、预热数据字典缓存、初始化定时任务调度器、初始化 HTTP 缓存与请求限流器,最后打印启动横幅。
  • 关闭期:反向释放资源,关闭调度器、清理缓存、卸载全局事件、释放数据库引擎连接池。

任意一步初始化失败都会直接中断并以非零状态退出,避免带病运行。app_init.py 同时定义了中间件的注册(按声明顺序)、静态文件挂载以及 Swagger/ReDoc 文档入口的重置(当配置中关闭文档时一并关闭 OpenAPI Schema,避免接口结构泄露)。

后端配置 ​

配置由 app/config/settings.py 中的 Settings 类承载,基于 pydantic-settings 实现。加载规则如下:

  • 根据环境变量 ENVIRONMENT(dev 或 prod)读取对应的 .env.dev / .env.prod 文件(位于 backend/env/)。
  • 通过 lru_cache 缓存单例 settings,全项目统一引用,避免重复解析。
  • 区分大小写,文件中未出现的项使用类内默认值。

配置按主题分组,覆盖服务器、API 文档、数据库、Redis、日志、跨域、登录认证、验证码、第三方 OAuth、WebSocket、Gzip、文件上传、请求限流等。其中几类以 @property 形式提供的"动态配置"尤其关键:

  • MIDDLEWARE_LIST:根据开关(如 GZIP_ENABLE、CORS_ORIGIN_ENABLE)动态决定是否挂载对应中间件。
  • EVENT_LIST:根据 REDIS_ENABLE 等开关决定启动时加载哪些全局事件模块。
  • ASYNC_DB_URI / DB_URI:根据 DATABASE_TYPE(mysql / postgres )拼接同步与异步连接串。
  • FASTAPI_CONFIG:组装 FastAPI 实例化参数(标题、版本、文档开关、统一响应状态码等)。

前端配置 ​

后端通过以下配置与前端协同,部署时需前后端对齐:

  • ROOT_PATH = "/api/v1":所有 API 的统一前缀,前端请求基地址应指向该路径。
  • CORS_ORIGIN_ENABLE 及 ALLOW_ORIGINS / ALLOW_METHODS / ALLOW_HEADERS:控制跨域,开发环境常设为放行,生产环境应缩窄到具体域名。
  • DOCS_URL / REDOC_URL:API 文档入口(如 /docs、/redoc),生产环境建议置空关闭。

后端以 /api/v1 作为统一路由前缀,并依赖 CORS 配置允许前端跨域访问;文档入口、演示模式、跨域白名单等开关均可在对应环境的 .env 文件中调整。

事件机制 ​

"全局事件"是一组在应用启动/关闭时被统一调用的初始化函数,由 settings.EVENT_LIST 声明、通过 framework/util/import_util.py 的 import_modules_async 动态导入并执行。以 Redis 为例:

机制要点:

  • 事件函数统一接收 app 与 status 两个参数,status=True 表示启动、False 表示关闭,同一函数据此双向处理资源。
  • 初始化结果挂载在 app.state 上(如 app.state.redis),后续各层通过依赖注入或 app.state 直接取用,无需自行建立连接。
  • 通过往 EVENT_LIST 追加可导入的路径字符串即可扩展新的全局事件,框架会在生命周期内自动调用,无需改动 app_init 主体代码。