# API 命名规范统一修复总结 ## 📋 问题描述 前后端 API 字段命名风格不一致,导致前后端交互失败: - **后端 Go JSON tags**: 使用 `snake_case` (如 `cluster_id`, `ca_data`) - **OpenAPI 规范**: 使用 `camelCase` (如 `clusterId`, `caData`) - **前端生成代码**: 使用 `camelCase`,与后端实际返回的JSON不匹配 - **前端手写代码**: 为了临时修复,手动使用 `snake_case` ## ✅ 解决方案 **选择方案B**: 统一使用 `snake_case` 作为业务数据字段命名规范 ### 命名规范标准 1. **OpenAPI 自身规范字段**: 保持 `camelCase` (如 `operationId`, `requestBody`) 2. **业务数据字段**: 统一使用 `snake_case` (与后端 Go JSON tags 一致) ### 优势 - ✅ 保持后端代码不变,降低改动成本 - ✅ Go 的 JSON 序列化默认就是字段名,使用 snake_case 更符合 Go 生态 - ✅ 前端自动生成的代码与后端完全匹配 - ✅ 无需手动维护类型定义 ## 🔧 修改内容 ### 1. 后端 DTO (保持不变) ```go // backend/internal/adapter/input/http/dto/cluster_dto.go type CreateClusterRequest struct { Name string `json:"name" binding:"required"` Host string `json:"host" binding:"required"` CAData string `json:"ca_data"` // ✅ snake_case CertData string `json:"cert_data"` // ✅ snake_case KeyData string `json:"key_data"` // ✅ snake_case Token string `json:"token"` Description string `json:"description"` } type ClusterResponse struct { ID string `json:"id"` Name string `json:"name"` // ... CreatedAt string `json:"created_at"` // ✅ snake_case UpdatedAt string `json:"updated_at"` // ✅ snake_case } ``` ### 2. OpenAPI 规范修改 **修改文件**: `backend/docs/openapi.yaml` #### 修改的 Schema: 1. **CreateClusterRequest** - `caData` → `ca_data` - `certData` → `cert_data` - `keyData` → `key_data` 2. **UpdateClusterRequest** - `caData` → `ca_data` - `certData` → `cert_data` - `keyData` → `key_data` 3. **ClusterResponse** - `createdAt` → `created_at` - `updatedAt` → `updated_at` 4. **RegistryResponse** - `createdAt` → `created_at` - `updatedAt` → `updated_at` 5. **UserResponse** - `createdAt` → `created_at` - `updatedAt` → `updated_at` 6. **InstanceResponse** - `clusterId` → `cluster_id` ✅ - `registryId` → `registry_id` ✅ (新增字段) - `repository` ✅ (新增字段) ### 3. 前端生成代码 重新生成前端 TypeScript API 客户端: ```bash bash scripts/sync-openapi-frontend.sh ``` **生成结果**: - ✅ 7 个 API 文件 - ✅ 25 个 Model 文件 - ✅ 完全匹配后端 JSON 字段命名 **示例生成代码**: ```typescript // frontend/src/api/generated/models/create-cluster-request.ts export interface CreateClusterRequest { 'name': string; 'host': string; 'ca_data'?: string; // ✅ snake_case 'cert_data'?: string; // ✅ snake_case 'key_data'?: string; // ✅ snake_case 'token'?: string; } // frontend/src/api/generated/models/instance-response.ts export interface InstanceResponse { 'id'?: string; 'name'?: string; 'namespace'?: string; 'cluster_id'?: string; // ✅ snake_case 'registry_id'?: string; // ✅ snake_case 'repository'?: string; // ... } ``` ## 📊 影响范围 ### 已修改 1. ✅ `backend/docs/openapi.yaml` - OpenAPI 规范 2. ✅ `frontend/src/api/generated/*` - 自动生成的 TypeScript 代码 ### 无需修改 1. ✅ 后端 Go DTO 代码 - 保持原有 snake_case 2. ✅ 前端手写的临时修复代码 - 现在可以使用生成的代码替换 ## 🎯 后续工作 ### 可选优化(前端) 前端中手写的类型定义现在可以删除,直接使用生成的代码: **需要清理的文件**: - `frontend/src/core/types/index.ts` - 包含手写的 snake_case 类型 - `frontend/src/core/api/instance.api.ts` - 包含手写的接口定义 - `frontend/src/core/api/unified-api.ts` - 包含手写的接口定义 **推荐做法**: 直接导入并使用自动生成的类型: ```typescript import { ClusterResponse, CreateClusterRequest, InstanceResponse } from '@/api/generated'; ``` ## ✅ 验证 ### 字段命名一致性检查 | 字段 | 后端 JSON | OpenAPI | 前端生成 | 状态 | |------|-----------|---------|----------|------| | `ca_data` | ✅ | ✅ | ✅ | 一致 | | `cert_data` | ✅ | ✅ | ✅ | 一致 | | `key_data` | ✅ | ✅ | ✅ | 一致 | | `cluster_id` | ✅ | ✅ | ✅ | 一致 | | `registry_id` | ✅ | ✅ | ✅ | 一致 | | `created_at` | ✅ | ✅ | ✅ | 一致 | | `updated_at` | ✅ | ✅ | ✅ | 一致 | ## 📝 注意事项 1. **OpenAPI 规范字段仍使用 camelCase**: 如 `operationId`, `requestBody` 等元字段 2. **业务数据字段统一 snake_case**: 所有 schemas 中的属性 3. **前端需更新代码**: 如果有直接使用手写类型的地方,需要切换到生成的类型 ## 🔗 相关文件 - OpenAPI 规范: `backend/docs/openapi.yaml` - 生成脚本: `scripts/sync-openapi-frontend.sh` - 前端生成代码: `frontend/src/api/generated/` - 后端 DTO: `backend/internal/adapter/input/http/dto/` --- **修复日期**: 2025-11-10 **修复人**: AI Assistant **影响版本**: OCDP v1.0.0