# RESTful API 设计

<cite>
**本文引用的文件**
- [README.md](file://README.md)
- [AGENTS.MD](file://AGENTS.MD)
- [public/api.php](file://public/api.php)
- [public/index.php](file://public/index.php)
- [public/router.php](file://public/router.php)
- [public/plugins/swagger/SwaggerPlugin.php](file://public/plugins/swagger/SwaggerPlugin.php)
- [public/plugins/swagger/service/OpenApi.php](file://public/plugins/swagger/service/OpenApi.php)
- [public/plugins/swagger/swagger/OpenApiSpec.php](file://public/plugins/swagger/swagger/OpenApiSpec.php)
- [public/plugins/swagger/controller/IndexController.php](file://public/plugins/swagger/controller/IndexController.php)
- [public/plugins/swagger/controller/ApiAdminIndexController.php](file://public/plugins/swagger/controller/ApiAdminIndexController.php)
- [public/plugins/swagger/view/swagger.html](file://public/plugins/swagger/view/swagger.html)
- [public/plugins/system_info/controller/ApiIndexController.php](file://public/plugins/system_info/controller/ApiIndexController.php)
- [public/themes/admin_default/admin/rbac/api_authorize.html](file://public/themes/admin_default/admin/rbac/api_authorize.html)
- [public/static/js/admin.js](file://public/static/js/admin.js)
- [public/static/js/frontend.js](file://public/static/js/frontend.js)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本指南面向 ThinkCMF 的 RESTful API 设计与实现，结合仓库中的 API 入口、Swagger 文档生成与权限集成、以及示例插件 API，系统阐述资源导向设计、URI 设计、HTTP 方法使用、状态码规范、版本控制策略与数据序列化约定，并给出用户、文章、分类等资源设计模式与最佳实践。

## 项目结构
- API 入口与路由
  - API 应用入口位于 public/api.php，定义命名空间为 api 并启动 HTTP 应用。
  - 站点入口 public/index.php 与 public/router.php 分别负责站点应用与伪静态路由转发。
- Swagger 文档体系
  - 插件 public/plugins/swagger 提供 OpenAPI 规范扫描、生成与后台导入、前端展示。
  - OpenApiSpec.php 定义 Info、Server、SecurityScheme、通用参数与响应模板。
  - IndexController 提供文档页面与 JSON 配置输出；ApiAdminIndexController 提供后台 API 导入接口。
- 示例插件 API
  - public/plugins/system_info/controller/ApiIndexController.php 展示了基于插件 REST 基类的 GET 接口示例。
- 权限与授权
  - 后台 API 权限导入与授权页面，支持从 OpenAPI 扫描结果导入后台 API 列表并绑定到权限规则。
- 前端交互
  - admin.js 与 frontend.js 对响应中的 code 字段进行统一处理，区分成功与失败分支。

```mermaid
graph TB
client["客户端"] --> api_entry["API 入口<br/>public/api.php"]
api_entry --> router["路由/中间件层"]
router --> controllers["控制器<br/>api/*/*/controller/*Controller"]
controllers --> swagger["Swagger 插件<br/>扫描/生成/导入"]
controllers --> docs["Swagger 文档页面<br/>/swagger"]
controllers --> rbac["后台权限授权<br/>/admin/roles/{id}/api/authorize"]
```

**图表来源**
- [public/api.php:1-41](file://public/api.php#L1-L41)
- [public/plugins/swagger/controller/IndexController.php:18-40](file://public/plugins/swagger/controller/IndexController.php#L18-L40)
- [public/plugins/swagger/SwaggerPlugin.php:32-103](file://public/plugins/swagger/SwaggerPlugin.php#L32-L103)
- [public/themes/admin_default/admin/rbac/api_authorize.html:12-42](file://public/themes/admin_default/admin/rbac/api_authorize.html#L12-L42)

**章节来源**
- [public/api.php:1-41](file://public/api.php#L1-L41)
- [public/index.php:1-37](file://public/index.php#L1-L37)
- [public/router.php:1-20](file://public/router.php#L1-L20)
- [README.md:103-113](file://README.md#L103-L113)

## 核心组件
- API 入口与命名空间
  - public/api.php 将应用命名空间定义为 api，确保 API 应用控制器位于 api\{应用}\controller 命名空间下。
- Swagger 文档与扫描
  - OpenApi::generate() 扫描 api 应用、vendor/thinkcmf/cmf-api 内置应用及已启用插件的 controller 与 swagger 目录，生成 OpenAPI JSON。
  - SwaggerPlugin::adminApiImportView() 将扫描结果导入后台 API 列表与权限规则。
- OpenAPI 规范
  - OpenApiSpec.php 定义服务器地址、安全方案（设备类型、API 版本、Authorization）、通用分页参数与成功/错误响应模板。
- 插件 REST API 示例
  - SystemInfo 插件 ApiIndexController 使用插件 REST 基类，提供 GET 接口示例。
- 权限与授权
  - 后台页面通过 PUT 请求向 /admin/roles/{id}/api/authorize 授权 API 权限，配合 Swagger 导入功能批量同步。

**章节来源**
- [public/api.php:28](file://public/api.php#L28)
- [public/plugins/swagger/service/OpenApi.php:10-64](file://public/plugins/swagger/service/OpenApi.php#L10-L64)
- [public/plugins/swagger/SwaggerPlugin.php:44-103](file://public/plugins/swagger/SwaggerPlugin.php#L44-L103)
- [public/plugins/swagger/swagger/OpenApiSpec.php:6-69](file://public/plugins/swagger/swagger/OpenApiSpec.php#L6-L69)
- [public/plugins/system_info/controller/ApiIndexController.php:21-57](file://public/plugins/system_info/controller/ApiIndexController.php#L21-L57)
- [public/themes/admin_default/admin/rbac/api_authorize.html:12](file://public/themes/admin_default/admin/rbac/api_authorize.html#L12)

## 架构总览
ThinkCMF 的 RESTful API 架构围绕以下要点展开：
- 资源导向：以资源为中心设计 URI，如 /plugin/{插件}/api_admin_index/index。
- 统一入口：API 应用通过 public/api.php 启动，控制器位于 api\{应用}\controller 命名空间。
- 文档驱动：通过 Swagger 插件扫描注解生成 OpenAPI 规范，支持后台导入与前端展示。
- 权限控制：后台 API 权限通过 RBAC 授权，支持从 OpenAPI 导入。
- 响应规范：前后端约定统一响应结构（含 code、msg、data），便于前端统一处理。

```mermaid
graph TB
subgraph "API 应用"
A["public/api.php"]
B["api/*/*/controller/*Controller"]
end
subgraph "Swagger 插件"
C["service/OpenApi.php"]
D["swagger/OpenApiSpec.php"]
E["controller/IndexController.php"]
F["controller/ApiAdminIndexController.php"]
G["SwaggerPlugin.php"]
end
subgraph "后台"
H["RBAC 授权页面<br/>api_authorize.html"]
end
A --> B
B --> C
C --> D
E --> D
F --> C
G --> C
H --> F
```

**图表来源**
- [public/api.php:1-41](file://public/api.php#L1-L41)
- [public/plugins/swagger/service/OpenApi.php:10-64](file://public/plugins/swagger/service/OpenApi.php#L10-L64)
- [public/plugins/swagger/swagger/OpenApiSpec.php:6-69](file://public/plugins/swagger/swagger/OpenApiSpec.php#L6-L69)
- [public/plugins/swagger/controller/IndexController.php:18-40](file://public/plugins/swagger/controller/IndexController.php#L18-L40)
- [public/plugins/swagger/controller/ApiAdminIndexController.php:21-48](file://public/plugins/swagger/controller/ApiAdminIndexController.php#L21-L48)
- [public/plugins/swagger/SwaggerPlugin.php:44-103](file://public/plugins/swagger/SwaggerPlugin.php#L44-L103)
- [public/themes/admin_default/admin/rbac/api_authorize.html:12-42](file://public/themes/admin_default/admin/rbac/api_authorize.html#L12-L42)

## 详细组件分析

### Swagger 文档与扫描服务
- 扫描范围
  - 自动扫描 api 应用、vendor/thinkcmf/cmf-api 内置应用及其 swagger 目录，以及已启用插件的 controller 与 swagger 目录。
- 生成与导出
  - 生成 OpenAPI JSON，IndexController::config() 输出 JSON 并设置跨域头，供 Swagger UI 使用。
  - SwaggerPlugin::adminApiImportView() 将扫描结果导入后台 admin_api 表与 auth_rule 权限规则。
- 安全与参数
  - OpenApiSpec.php 定义设备类型、API 版本与 Authorization 头部安全方案，以及通用分页参数与成功/错误响应模板。

```mermaid
sequenceDiagram
participant Dev as "开发者"
participant Ctrl as "ApiAdminIndexController"
participant Svc as "OpenApi : : generate()"
participant DB as "后台数据库"
participant UI as "Swagger UI"
Dev->>Ctrl : "POST /plugin/swagger/api_admin_index/importApi"
Ctrl->>Svc : "扫描并生成 OpenAPI JSON"
Svc-->>Ctrl : "返回 JSON"
Ctrl->>DB : "导入 admin_api 与 auth_rule"
DB-->>Ctrl : "完成"
Ctrl-->>Dev : "导入成功响应"
Dev->>UI : "访问 /swagger 查看文档"
UI->>Ctrl : "GET /plugin/swagger/config"
Ctrl-->>UI : "返回 OpenAPI JSON"
```

**图表来源**
- [public/plugins/swagger/controller/ApiAdminIndexController.php:21-48](file://public/plugins/swagger/controller/ApiAdminIndexController.php#L21-L48)
- [public/plugins/swagger/service/OpenApi.php:10-64](file://public/plugins/swagger/service/OpenApi.php#L10-L64)
- [public/plugins/swagger/SwaggerPlugin.php:44-103](file://public/plugins/swagger/SwaggerPlugin.php#L44-L103)
- [public/plugins/swagger/controller/IndexController.php:29-39](file://public/plugins/swagger/controller/IndexController.php#L29-L39)

**章节来源**
- [public/plugins/swagger/service/OpenApi.php:10-64](file://public/plugins/swagger/service/OpenApi.php#L10-L64)
- [public/plugins/swagger/SwaggerPlugin.php:44-103](file://public/plugins/swagger/SwaggerPlugin.php#L44-L103)
- [public/plugins/swagger/swagger/OpenApiSpec.php:6-69](file://public/plugins/swagger/swagger/OpenApiSpec.php#L6-L69)
- [public/plugins/swagger/controller/IndexController.php:18-40](file://public/plugins/swagger/controller/IndexController.php#L18-L40)

### 插件 REST API 示例（SystemInfo）
- 设计要点
  - 使用插件 REST 基类，提供 GET 接口，返回统一响应结构（code、msg、data）。
  - 通过注解声明路径、标签、摘要与响应示例，纳入 Swagger 扫描。
- 响应处理
  - 前端脚本根据响应中的 code 字段区分成功与失败，执行相应 UI 反馈或刷新。

```mermaid
sequenceDiagram
participant Client as "客户端"
participant Ctrl as "SystemInfo ApiIndexController"
participant DB as "数据库"
participant View as "Swagger UI"
Client->>Ctrl : "GET /plugin/system_info/api_admin_index/index"
Ctrl->>DB : "查询系统信息"
DB-->>Ctrl : "返回结果"
Ctrl-->>Client : "统一响应结构"
Client->>View : "查看注解文档"
```

**图表来源**
- [public/plugins/system_info/controller/ApiIndexController.php:21-57](file://public/plugins/system_info/controller/ApiIndexController.php#L21-L57)
- [public/plugins/swagger/view/swagger.html:36-56](file://public/plugins/swagger/view/swagger.html#L36-L56)

**章节来源**
- [public/plugins/system_info/controller/ApiIndexController.php:21-57](file://public/plugins/system_info/controller/ApiIndexController.php#L21-L57)
- [public/plugins/swagger/view/swagger.html:36-56](file://public/plugins/swagger/view/swagger.html#L36-L56)

### 权限与授权（RBAC）
- 授权流程
  - 后台页面通过 PUT 请求向 /admin/roles/{id}/api/authorize 授权 API 权限。
  - Swagger 插件可将扫描到的后台 API 导入到后台 API 列表与权限规则，便于统一授权。
- 前端交互
  - admin.js 与 frontend.js 对响应中的 code 字段进行统一处理，区分成功与失败分支。

```mermaid
flowchart TD
Start(["开始"]) --> Scan["扫描 OpenAPI"]
Scan --> Import["导入后台 API 列表与权限规则"]
Import --> Grant["后台授权页面勾选权限"]
Grant --> PutReq["PUT /admin/roles/{id}/api/authorize"]
PutReq --> Done(["完成"])
```

**图表来源**
- [public/plugins/swagger/SwaggerPlugin.php:44-103](file://public/plugins/swagger/SwaggerPlugin.php#L44-L103)
- [public/themes/admin_default/admin/rbac/api_authorize.html:12-42](file://public/themes/admin_default/admin/rbac/api_authorize.html#L12-L42)
- [public/static/js/admin.js:336-343](file://public/static/js/admin.js#L336-L343)

**章节来源**
- [public/themes/admin_default/admin/rbac/api_authorize.html:12-42](file://public/themes/admin_default/admin/rbac/api_authorize.html#L12-L42)
- [public/static/js/admin.js:336-343](file://public/static/js/admin.js#L336-L343)

## 依赖分析
- 控制器基类层次
  - ThinkPHP 基类 → CMF 基类 → REST 基类（RestBaseController、RestUserBaseController、RestAdminBaseController）。
- API 入口与命名空间
  - public/api.php 将命名空间定义为 api，API 控制器位于 api\{应用}\controller 命名空间。
- Swagger 依赖
  - OpenApi::generate() 依赖 Doctrine Annotations 扫描注解，生成 OpenAPI JSON。
- 前端依赖
  - admin.js 与 frontend.js 依赖统一响应结构（code、msg、data）进行 UI 反馈。

```mermaid
graph LR
TP["ThinkPHP 基类"] --> Base["CMF 基类"]
Base --> Rest["REST 基类"]
Rest --> RestUser["RestUserBaseController"]
Rest --> RestAdmin["RestAdminBaseController"]
APIEntry["public/api.php"] --> NS["命名空间 api/*/*/controller"]
SwaggerSvc["OpenApi::generate()"] --> OA["OpenAPI JSON"]
FrontAdmin["admin.js"] --> Resp["统一响应结构"]
FrontFront["frontend.js"] --> Resp
```

**图表来源**
- [AGENTS.MD:182-210](file://AGENTS.MD#L182-L210)
- [public/api.php:28](file://public/api.php#L28)
- [public/plugins/swagger/service/OpenApi.php:10-64](file://public/plugins/swagger/service/OpenApi.php#L10-L64)
- [public/static/js/admin.js:336-343](file://public/static/js/admin.js#L336-L343)
- [public/static/js/frontend.js:445-458](file://public/static/js/frontend.js#L445-L458)

**章节来源**
- [AGENTS.MD:182-210](file://AGENTS.MD#L182-L210)
- [public/api.php:28](file://public/api.php#L28)
- [public/plugins/swagger/service/OpenApi.php:10-64](file://public/plugins/swagger/service/OpenApi.php#L10-L64)
- [public/static/js/admin.js:336-343](file://public/static/js/admin.js#L336-L343)
- [public/static/js/frontend.js:445-458](file://public/static/js/frontend.js#L445-L458)

## 性能考量
- 文档生成扫描范围
  - OpenApi::generate() 会扫描多个目录（api 应用、vendor/thinkcmf/cmf-api、已启用插件），建议在生产环境避免频繁触发扫描，可通过缓存策略减少扫描成本。
- 跨域与响应
  - IndexController::config() 设置跨域头，适用于前后端分离场景；注意仅在必要时开启，避免不必要的 CORS 影响。
- 前端统一处理
  - admin.js 与 frontend.js 对响应进行统一处理，减少重复逻辑，提升前端一致性与可维护性。

**章节来源**
- [public/plugins/swagger/service/OpenApi.php:10-64](file://public/plugins/swagger/service/OpenApi.php#L10-L64)
- [public/plugins/swagger/controller/IndexController.php:29-39](file://public/plugins/swagger/controller/IndexController.php#L29-L39)
- [public/static/js/admin.js:272-343](file://public/static/js/admin.js#L272-L343)
- [public/static/js/frontend.js:240-476](file://public/static/js/frontend.js#L240-L476)

## 故障排查指南
- Swagger 文档不可见
  - 确认已安装 Swagger 插件且 APP_DEBUG 或已登录后台；IndexController::index() 仅在调试或后台登录状态下允许访问。
- 导入后台 API 失败
  - 检查 OpenApi::generate() 是否成功扫描到目标控制器与注解；确认 SwaggerPlugin::adminApiImportView() 的导入逻辑是否执行。
- 响应 code 不一致
  - 前端 admin.js 与 frontend.js 依赖响应中的 code 字段进行分支处理；确保后端接口返回统一结构（code、msg、data）。
- 权限授权无效
  - 确认 Swagger 导入的后台 API 列表与权限规则已正确写入数据库；后台授权页面需勾选对应权限并提交 PUT 请求。

**章节来源**
- [public/plugins/swagger/controller/IndexController.php:20-27](file://public/plugins/swagger/controller/IndexController.php#L20-L27)
- [public/plugins/swagger/SwaggerPlugin.php:44-103](file://public/plugins/swagger/SwaggerPlugin.php#L44-L103)
- [public/static/js/admin.js:336-343](file://public/static/js/admin.js#L336-L343)
- [public/themes/admin_default/admin/rbac/api_authorize.html:12-42](file://public/themes/admin_default/admin/rbac/api_authorize.html#L12-L42)

## 结论
ThinkCMF 的 RESTful API 设计以资源为导向，通过统一入口、Swagger 文档驱动与 RBAC 权限控制，形成清晰的 API 开发生态。结合统一响应结构与前端统一处理，能够快速构建稳定、可维护的 API。建议在生产环境中合理缓存 Swagger 扫描结果，严格遵循状态码与版本控制策略，持续完善资源模型与嵌套关系设计。

## 附录

### RESTful 架构核心原则与设计模式
- 资源导向设计
  - 以名词表示资源，如 /plugin/{插件}/api_admin_index/index。
- 统一资源标识符（URI）
  - 使用层级与参数表达资源关系，如 /users/{id}/articles/{article_id}。
- HTTP 方法使用
  - GET：获取资源或集合；POST：创建资源；PUT/PATCH：更新资源；DELETE：删除资源。
- 响应与状态码
  - 成功：200/201/204；客户端错误：400/401/403/404/422；服务器错误：500。
- 版本控制
  - 采用头部版本控制（XX-Api-Version），保持向后兼容与演进路径。
- 数据序列化
  - JSON 作为默认序列化格式，XML 作为可选；优先保证 JSON 的一致性与易用性。

### API 应用结构与组织
- 命名空间与入口
  - API 应用命名空间为 api，控制器位于 api\{应用}\controller。
- Swagger 集成
  - 通过注解与 OpenApi 扫描生成文档，支持后台导入与权限绑定。
- 权限与授权
  - RBAC 授权页面支持批量导入与勾选授权，PUT 请求完成授权。

**章节来源**
- [public/api.php:28](file://public/api.php#L28)
- [public/plugins/swagger/swagger/OpenApiSpec.php:6-69](file://public/plugins/swagger/swagger/OpenApiSpec.php#L6-L69)
- [public/themes/admin_default/admin/rbac/api_authorize.html:12-42](file://public/themes/admin_default/admin/rbac/api_authorize.html#L12-L42)