API 管理规范
1. 技能概述
本技能提供了家族树应用的API管理规范,包括API设计规范、API契约定义、最佳实践和错误处理等。通过本规范,开发者可以确保API设计的一致性、可维护性和安全性。
2. API设计规范
2.1 参数传递规范
禁止:将参数直接放在URL路径中
❌ 错误示例:
/families/{familyId}/members
/members/{memberId}/relationships
允许:
- GET请求:使用查询参数(query parameters)传递参数
- POST/PUT请求:使用请求体(request body)传递参数
- 资源ID:只有资源的唯一标识符(ID)可以放在URL路径中
✅ 正确示例:
- GET请求:
/members/family?familyId=1
- POST请求:
/members 配合请求体 { "familyId": 1, "name": "张三" }
- 资源获取:
/members/1(这里的1是成员ID,属于资源标识符)
2.2 规范原因
- 安全性:敏感参数不应该暴露在URL中
- 可读性:URL更清晰,参数语义更明确
- 一致性:统一的参数传递方式便于维护
- 灵活性:查询参数和请求体可以更好地处理复杂参数
2.3 常见场景处理
2.3.1 根据父资源获取子资源列表
❌ 错误:
GET /api/families/{familyId}/members
✅ 正确:
GET /api/members/family?familyId=1
2.3.2 创建子资源
❌ 错误:
POST /api/families/{familyId}/members
{
"name": "张三"
}
✅ 正确:
POST /api/members
{
"familyId": 1,
"name": "张三"
}
2.3.3 获取单个资源(允许使用ID在URL中)
✅ 允许:
GET /api/members/1
PUT /api/members/1
DELETE /api/members/1
2.4 代码示例
2.4.1 后端Spring Boot示例
2.4.1.1 错误的实现(禁止)
@RestController
@RequestMapping("/api")
public class MemberController {
// ❌ 禁止:familyId在URL路径中
@GetMapping("/families/{familyId}/members")
public ApiResponse<List<Member>> getMembers(@PathVariable Long familyId) {
// ...
}
// ❌ 禁止:familyId在URL路径中
@PostMapping("/families/{familyId}/members")
public ApiResponse<Member> addMember(
@PathVariable Long familyId,
@RequestBody Member member) {
// ...
}
}
2.4.1.2 正确的实现(推荐)
@RestController
@RequestMapping("/api")
public class MemberController {
// ✅ 正确:使用查询参数
@GetMapping("/members/family")
public ApiResponse<List<Member>> getMembers(@RequestParam Long familyId) {
// ...
}
// ✅ 正确:使用请求体
@PostMapping("/members")
public ApiResponse<Member> addMember(@RequestBody Member member) {
// member对象中包含familyId字段
// ...
}
}
2.4.2 前端Vue示例
2.4.2.1 错误的实现(禁止)
// ❌ 禁止:familyId在URL路径中
async fetchMembersByFamilyId(familyId) {
const response = await api.get(`/families/${familyId}/members`)
// ...
}
// ❌ 禁止:familyId在URL路径中
async createMember(memberData) {
const { familyId, ...memberDataWithoutFamilyId } = memberData
const response = await api.post(`/families/${familyId}/members`, memberDataWithoutFamilyId)
// ...
}
2.4.2.2 正确的实现(推荐)
// ✅ 正确:使用查询参数
async fetchMembersByFamilyId(familyId) {
const response = await api.get('/members/family', {
params: { familyId }
})
// ...
}
// ✅ 正确:使用请求体
async createMember(memberData) {
const response = await api.post('/members', memberData)
// memberData对象中包含familyId字段
// ...
}
3. API契约定义
3.1 认证相关 API
3.1.1 登录
请求
响应
3.1.2 注册
请求
响应
- 状态码:
201 Created
- 响应体:
{
"id": 1,
"email": "user@example.com",
"nickname": "用户昵称",
"avatar": null,
"phone": null,
"createdAt": "2024-01-01T00:00:00"
}
3.1.3 获取当前用户信息
请求
- URL:
/api/auth/me
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"email": "user@example.com",
"nickname": "用户昵称",
"avatar": null,
"phone": null,
"createdAt": "2024-01-01T00:00:00"
}
3.2 家族管理 API
3.2.1 创建家族
请求
响应
- 状态码:
201 Created
- 响应体:
{
"id": 1,
"name": "我的家族",
"description": "这是我的家族",
"avatar": "https://example.com/avatar.jpg",
"creatorId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.2.2 获取家族列表
请求
- URL:
/api/families
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
[
{
"id": 1,
"name": "我的家族",
"description": "这是我的家族",
"avatar": "https://example.com/avatar.jpg",
"creatorId": 1,
"createdAt": "2024-01-01T00:00:00"
}
]
3.2.3 获取家族详情
请求
- URL:
/api/families/{id}
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"name": "我的家族",
"description": "这是我的家族",
"avatar": "https://example.com/avatar.jpg",
"creatorId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.2.4 更新家族
请求
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"name": "更新后的家族名称",
"description": "更新后的家族描述",
"avatar": "https://example.com/new-avatar.jpg",
"creatorId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.2.5 删除家族
请求
- URL:
/api/families/{id}
- 方法:
DELETE
- 请求头:
Authorization: Bearer <token>
响应
3.3 成员管理 API
3.3.1 添加成员
请求
- URL:
/api/members
- 方法:
POST
- 请求头:
Authorization: Bearer <token>
- 内容类型:
application/json
- 请求体:
{
"familyId": 1,
"name": "张三",
"gender": "MALE",
"birthDate": "1980-01-01",
"deathDate": null,
"photo": "https://example.com/photo.jpg",
"details": "这是成员详情"
}
响应
- 状态码:
201 Created
- 响应体:
{
"id": 1,
"name": "张三",
"gender": "MALE",
"birthDate": "1980-01-01",
"deathDate": null,
"photo": "https://example.com/photo.jpg",
"details": "这是成员详情",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.3.2 获取成员列表
请求
- URL:
/api/members/family
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
- 查询参数:
familyId=1
响应
- 状态码:
200 OK
- 响应体:
[
{
"id": 1,
"name": "张三",
"gender": "MALE",
"birthDate": "1980-01-01",
"deathDate": null,
"photo": "https://example.com/photo.jpg",
"details": "这是成员详情",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
]
3.3.3 获取成员详情
请求
- URL:
/api/members/{id}
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"name": "张三",
"gender": "MALE",
"birthDate": "1980-01-01",
"deathDate": null,
"photo": "https://example.com/photo.jpg",
"details": "这是成员详情",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.3.4 更新成员
请求
- URL:
/api/members/{id}
- 方法:
PUT
- 请求头:
Authorization: Bearer <token>
- 内容类型:
application/json
- 请求体:
{
"name": "张三(更新)",
"gender": "MALE",
"birthDate": "1980-01-01",
"deathDate": null,
"photo": "https://example.com/new-photo.jpg",
"details": "更新后的成员详情"
}
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"name": "张三(更新)",
"gender": "MALE",
"birthDate": "1980-01-01",
"deathDate": null,
"photo": "https://example.com/new-photo.jpg",
"details": "更新后的成员详情",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.3.5 删除成员
请求
- URL:
/api/members/{id}
- 方法:
DELETE
- 请求头:
Authorization: Bearer <token>
响应
3.4 关系管理 API
3.4.1 创建关系
请求
响应
- 状态码:
201 Created
- 响应体:
{
"id": 1,
"memberId1": 1,
"memberId2": 2,
"relationshipType": "FATHER",
"createdAt": "2024-01-01T00:00:00"
}
3.4.2 获取关系列表
请求
- URL:
/api/relationships
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
[
{
"id": 1,
"memberId1": 1,
"memberId2": 2,
"relationshipType": "FATHER",
"createdAt": "2024-01-01T00:00:00"
}
]
3.4.3 获取成员的关系
请求
- URL:
/api/relationships/member
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
- 查询参数:
memberId=1
响应
- 状态码:
200 OK
- 响应体:
[
{
"id": 1,
"memberId1": 1,
"memberId2": 2,
"relationshipType": "FATHER",
"createdAt": "2024-01-01T00:00:00"
}
]
3.4.4 删除关系
请求
- URL:
/api/relationships/{id}
- 方法:
DELETE
- 请求头:
Authorization: Bearer <token>
响应
3.5 事件管理 API
3.5.1 创建事件
请求
- URL:
/api/events
- 方法:
POST
- 请求头:
Authorization: Bearer <token>
- 内容类型:
application/json
- 请求体:
{
"title": "生日派对",
"description": "张三的生日派对",
"date": "2024-01-01",
"location": "家中",
"familyId": 1
}
响应
- 状态码:
201 Created
- 响应体:
{
"id": 1,
"title": "生日派对",
"description": "张三的生日派对",
"date": "2024-01-01",
"location": "家中",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.5.2 获取事件列表
请求
- URL:
/api/events
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
[
{
"id": 1,
"title": "生日派对",
"description": "张三的生日派对",
"date": "2024-01-01",
"location": "家中",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
]
3.5.3 获取事件详情
请求
- URL:
/api/events/{id}
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"title": "生日派对",
"description": "张三的生日派对",
"date": "2024-01-01",
"location": "家中",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.5.4 更新事件
请求
- URL:
/api/events/{id}
- 方法:
PUT
- 请求头:
Authorization: Bearer <token>
- 内容类型:
application/json
- 请求体:
{
"title": "生日派对(更新)",
"description": "张三的生日派对(更新)",
"date": "2024-01-02",
"location": "餐厅",
"familyId": 1
}
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"title": "生日派对(更新)",
"description": "张三的生日派对(更新)",
"date": "2024-01-02",
"location": "餐厅",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.5.5 删除事件
请求
- URL:
/api/events/{id}
- 方法:
DELETE
- 请求头:
Authorization: Bearer <token>
响应
3.6 媒体管理 API
3.6.1 上传媒体
请求
- URL:
/api/media
- 方法:
POST
- 请求头:
Authorization: Bearer <token>
- 内容类型:
multipart/form-data
- 请求体:
file: 文件
familyId: 家族ID
description: 描述
响应
- 状态码:
201 Created
- 响应体:
{
"id": 1,
"fileName": "photo.jpg",
"filePath": "/uploads/photo.jpg",
"description": "家族照片",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.6.2 获取媒体列表
请求
- URL:
/api/media
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
[
{
"id": 1,
"fileName": "photo.jpg",
"filePath": "/uploads/photo.jpg",
"description": "家族照片",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
]
3.6.3 获取媒体详情
请求
- URL:
/api/media/{id}
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"fileName": "photo.jpg",
"filePath": "/uploads/photo.jpg",
"description": "家族照片",
"familyId": 1,
"createdAt": "2024-01-01T00:00:00"
}
3.6.4 删除媒体
请求
- URL:
/api/media/{id}
- 方法:
DELETE
- 请求头:
Authorization: Bearer <token>
响应
3.7 权限管理 API
3.7.1 分配权限
请求
响应
- 状态码:
201 Created
- 响应体:
{
"id": 1,
"userId": 2,
"familyId": 1,
"role": "MEMBER",
"createdAt": "2024-01-01T00:00:00"
}
3.7.2 获取权限列表
请求
- URL:
/api/permissions
- 方法:
GET
- 请求头:
Authorization: Bearer <token>
响应
- 状态码:
200 OK
- 响应体:
[
{
"id": 1,
"userId": 2,
"familyId": 1,
"role": "MEMBER",
"createdAt": "2024-01-01T00:00:00"
}
]
3.7.3 更新权限
请求
- URL:
/api/permissions/{id}
- 方法:
PUT
- 请求头:
Authorization: Bearer <token>
- 内容类型:
application/json
- 请求体:
{
"role": "ADMIN"
}
响应
- 状态码:
200 OK
- 响应体:
{
"id": 1,
"userId": 2,
"familyId": 1,
"role": "ADMIN",
"createdAt": "2024-01-01T00:00:00"
}
3.7.4 删除权限
请求
- URL:
/api/permissions/{id}
- 方法:
DELETE
- 请求头:
Authorization: Bearer <token>
响应
4. 前端与后端交互示例
4.1 登录流程
// 前端登录请求
async function login(email, password) {
const response = await fetch('http://localhost:8080/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});
if (!response.ok) {
throw new Error('登录失败');
}
const data = await response.json();
localStorage.setItem('token', data.token);
return data;
}
4.2 获取家族列表
// 前端获取家族列表
async function getFamilies() {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:8080/api/families', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error('获取家族列表失败');
}
return await response.json();
}
4.3 添加成员
// 前端添加成员
async function addMember(memberData) {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:8080/api/members', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(memberData)
});
if (!response.ok) {
throw new Error('添加成员失败');
}
return await response.json();
}
5. 错误处理
5.1 常见错误状态码
| 状态码 |
描述 |
处理方式 |
| 400 |
请求参数错误 |
检查请求参数格式是否正确 |
| 401 |
未授权 |
重新登录获取新的token |
| 403 |
禁止访问 |
检查用户是否有相应权限 |
| 404 |
资源不存在 |
检查请求的资源ID是否正确 |
| 500 |
服务器内部错误 |
联系后端开发人员 |
5.2 错误处理示例
// 前端错误处理示例
try {
const data = await login(email, password);
// 处理成功逻辑
} catch (error) {
console.error('登录失败:', error.message);
// 显示错误提示
}
6. API版本管理
6.1 版本控制策略
- URL路径版本:
/api/v1/resource
- 头部版本:
Accept: application/vnd.familytree.v1+json
- 查询参数版本:
/api/resource?version=1
6.2 版本迁移策略
- 向后兼容:新版本应兼容旧版本API
- 弃用通知:提前通知API弃用计划
- 版本生命周期:明确每个版本的支持期限
7. API安全
7.1 认证与授权
- 使用JWT进行身份认证
- 基于角色的访问控制(RBAC)
- 权限验证中间件
7.2 安全最佳实践
- HTTPS传输
- 输入验证
- 速率限制
- 防止SQL注入
- 防止XSS攻击
- 防止CSRF攻击
8. API监控与分析
8.1 监控指标
8.2 分析工具
- Spring Boot Actuator
- Prometheus + Grafana
- ELK Stack(Elasticsearch, Logstash, Kibana)
9. 最佳实践
- 使用HTTPS:在生产环境中使用HTTPS协议保护API通信
- 合理使用缓存:对于不经常变化的数据,可以使用缓存减少API调用
- 分页处理:对于大量数据的API,使用分页参数减少数据传输量
- 错误处理:对所有API调用进行错误处理,确保用户体验
- 参数验证:在前端对用户输入进行验证,减少无效请求
- token管理:合理管理token的存储和刷新,确保安全性
- API文档:使用Swagger等工具自动生成API文档
- 版本控制:合理管理API版本,确保向后兼容性
- 监控:实现API监控,及时发现和解决问题
- 测试:为API编写单元测试和集成测试
10. 检查清单
在开发新的API接口时,请检查以下内容:
11. 规范执行
所有新开发的API接口必须严格遵守本规范。对于已有的不符合规范的接口,应在后续的迭代中逐步重构,以保持代码库的一致性。
12. 总结
本API管理规范提供了全面的API设计、实现和管理指南,包括:
- API设计规范:统一参数传递方式,提高代码可读性和安全性
- API契约定义:详细的API接口文档,便于前后端开发协作
- 错误处理:统一的错误处理机制,提高用户体验
- 安全措施:全面的API安全最佳实践
- 监控与分析:API性能监控和问题排查
- 最佳实践:行业标准的API开发规范
通过遵循本规范,开发者可以构建高质量、可维护、安全的API服务,为家族树应用提供可靠的后端支持。
1---2name: api-management3description: API 管理规范4---5# API 管理规范67## 1. 技能概述89本技能提供了家族树应用的API管理规范,包括API设计规范、API契约定义、最佳实践和错误处理等。通过本规范,开发者可以确保API设计的一致性、可维护性和安全性。1011## 2. API设计规范1213### 2.1 参数传递规范1415**禁止**:将参数直接放在URL路径中1617❌ 错误示例:18- `/families/{familyId}/members`19- `/members/{memberId}/relationships`2021**允许**:221. **GET请求**:使用查询参数(query parameters)传递参数232. **POST/PUT请求**:使用请求体(request body)传递参数243. **资源ID**:只有资源的唯一标识符(ID)可以放在URL路径中2526✅ 正确示例:27- **GET请求**:`/members/family?familyId=1`28- **POST请求**:`/members` 配合请求体 `{ "familyId": 1, "name": "张三" }`29- **资源获取**:`/members/1`(这里的1是成员ID,属于资源标识符)3031### 2.2 规范原因32331. **安全性**:敏感参数不应该暴露在URL中342. **可读性**:URL更清晰,参数语义更明确353. **一致性**:统一的参数传递方式便于维护364. **灵活性**:查询参数和请求体可以更好地处理复杂参数3738### 2.3 常见场景处理3940#### 2.3.1 根据父资源获取子资源列表4142❌ 错误:43```44GET /api/families/{familyId}/members45```4647✅ 正确:48```49GET /api/members/family?familyId=150```5152#### 2.3.2 创建子资源5354❌ 错误:55```56POST /api/families/{familyId}/members57{58 "name": "张三"59}60```6162✅ 正确:63```64POST /api/members65{66 "familyId": 1,67 "name": "张三"68}69```7071#### 2.3.3 获取单个资源(允许使用ID在URL中)7273✅ 允许:74```75GET /api/members/176PUT /api/members/177DELETE /api/members/178```7980### 2.4 代码示例8182#### 2.4.1 后端Spring Boot示例8384##### 2.4.1.1 错误的实现(禁止)8586```java87@RestController88@RequestMapping("/api")89public class MemberController {90 91 // ❌ 禁止:familyId在URL路径中92 @GetMapping("/families/{familyId}/members")93 public ApiResponse<List<Member>> getMembers(@PathVariable Long familyId) {94 // ...95 }96 97 // ❌ 禁止:familyId在URL路径中98 @PostMapping("/families/{familyId}/members")99 public ApiResponse<Member> addMember(100 @PathVariable Long familyId, 101 @RequestBody Member member) {102 // ...103 }104}105```106107##### 2.4.1.2 正确的实现(推荐)108109```java110@RestController111@RequestMapping("/api")112public class MemberController {113 114 // ✅ 正确:使用查询参数115 @GetMapping("/members/family")116 public ApiResponse<List<Member>> getMembers(@RequestParam Long familyId) {117 // ...118 }119 120 // ✅ 正确:使用请求体121 @PostMapping("/members")122 public ApiResponse<Member> addMember(@RequestBody Member member) {123 // member对象中包含familyId字段124 // ...125 }126}127```128129#### 2.4.2 前端Vue示例130131##### 2.4.2.1 错误的实现(禁止)132133```javascript134// ❌ 禁止:familyId在URL路径中135async fetchMembersByFamilyId(familyId) {136 const response = await api.get(`/families/${familyId}/members`)137 // ...138}139140// ❌ 禁止:familyId在URL路径中141async createMember(memberData) {142 const { familyId, ...memberDataWithoutFamilyId } = memberData143 const response = await api.post(`/families/${familyId}/members`, memberDataWithoutFamilyId)144 // ...145}146```147148##### 2.4.2.2 正确的实现(推荐)149150```javascript151// ✅ 正确:使用查询参数152async fetchMembersByFamilyId(familyId) {153 const response = await api.get('/members/family', {154 params: { familyId }155 })156 // ...157}158159// ✅ 正确:使用请求体160async createMember(memberData) {161 const response = await api.post('/members', memberData)162 // memberData对象中包含familyId字段163 // ...164}165```166167## 3. API契约定义168169### 3.1 认证相关 API170171#### 3.1.1 登录172173**请求**174- URL: `/api/auth/login`175- 方法: `POST`176- 内容类型: `application/json`177- 请求体:178 ```json179 {180 "email": "user@example.com",181 "password": "password123"182 }183 ```184185**响应**186- 状态码: `200 OK`187- 响应体:188 ```json189 {190 "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."191 }192 ```193194#### 3.1.2 注册195196**请求**197- URL: `/api/auth/register`198- 方法: `POST`199- 内容类型: `application/json`200- 请求体:201 ```json202 {203 "email": "user@example.com",204 "password": "password123",205 "nickname": "用户昵称"206 }207 ```208209**响应**210- 状态码: `201 Created`211- 响应体:212 ```json213 {214 "id": 1,215 "email": "user@example.com",216 "nickname": "用户昵称",217 "avatar": null,218 "phone": null,219 "createdAt": "2024-01-01T00:00:00"220 }221 ```222223#### 3.1.3 获取当前用户信息224225**请求**226- URL: `/api/auth/me`227- 方法: `GET`228- 请求头: `Authorization: Bearer <token>`229230**响应**231- 状态码: `200 OK`232- 响应体:233 ```json234 {235 "id": 1,236 "email": "user@example.com",237 "nickname": "用户昵称",238 "avatar": null,239 "phone": null,240 "createdAt": "2024-01-01T00:00:00"241 }242 ```243244### 3.2 家族管理 API245246#### 3.2.1 创建家族247248**请求**249- URL: `/api/families`250- 方法: `POST`251- 请求头: `Authorization: Bearer <token>`252- 内容类型: `application/json`253- 请求体:254 ```json255 {256 "name": "我的家族",257 "description": "这是我的家族",258 "avatar": "https://example.com/avatar.jpg"259 }260 ```261262**响应**263- 状态码: `201 Created`264- 响应体:265 ```json266 {267 "id": 1,268 "name": "我的家族",269 "description": "这是我的家族",270 "avatar": "https://example.com/avatar.jpg",271 "creatorId": 1,272 "createdAt": "2024-01-01T00:00:00"273 }274 ```275276#### 3.2.2 获取家族列表277278**请求**279- URL: `/api/families`280- 方法: `GET`281- 请求头: `Authorization: Bearer <token>`282283**响应**284- 状态码: `200 OK`285- 响应体:286 ```json287 [288 {289 "id": 1,290 "name": "我的家族",291 "description": "这是我的家族",292 "avatar": "https://example.com/avatar.jpg",293 "creatorId": 1,294 "createdAt": "2024-01-01T00:00:00"295 }296 ]297 ```298299#### 3.2.3 获取家族详情300301**请求**302- URL: `/api/families/{id}`303- 方法: `GET`304- 请求头: `Authorization: Bearer <token>`305306**响应**307- 状态码: `200 OK`308- 响应体:309 ```json310 {311 "id": 1,312 "name": "我的家族",313 "description": "这是我的家族",314 "avatar": "https://example.com/avatar.jpg",315 "creatorId": 1,316 "createdAt": "2024-01-01T00:00:00"317 }318 ```319320#### 3.2.4 更新家族321322**请求**323- URL: `/api/families/{id}`324- 方法: `PUT`325- 请求头: `Authorization: Bearer <token>`326- 内容类型: `application/json`327- 请求体:328 ```json329 {330 "name": "更新后的家族名称",331 "description": "更新后的家族描述",332 "avatar": "https://example.com/new-avatar.jpg"333 }334 ```335336**响应**337- 状态码: `200 OK`338- 响应体:339 ```json340 {341 "id": 1,342 "name": "更新后的家族名称",343 "description": "更新后的家族描述",344 "avatar": "https://example.com/new-avatar.jpg",345 "creatorId": 1,346 "createdAt": "2024-01-01T00:00:00"347 }348 ```349350#### 3.2.5 删除家族351352**请求**353- URL: `/api/families/{id}`354- 方法: `DELETE`355- 请求头: `Authorization: Bearer <token>`356357**响应**358- 状态码: `204 No Content`359360### 3.3 成员管理 API361362#### 3.3.1 添加成员363364**请求**365- URL: `/api/members`366- 方法: `POST`367- 请求头: `Authorization: Bearer <token>`368- 内容类型: `application/json`369- 请求体:370 ```json371 {372 "familyId": 1,373 "name": "张三",374 "gender": "MALE",375 "birthDate": "1980-01-01",376 "deathDate": null,377 "photo": "https://example.com/photo.jpg",378 "details": "这是成员详情"379 }380 ```381382**响应**383- 状态码: `201 Created`384- 响应体:385 ```json386 {387 "id": 1,388 "name": "张三",389 "gender": "MALE",390 "birthDate": "1980-01-01",391 "deathDate": null,392 "photo": "https://example.com/photo.jpg",393 "details": "这是成员详情",394 "familyId": 1,395 "createdAt": "2024-01-01T00:00:00"396 }397 ```398399#### 3.3.2 获取成员列表400401**请求**402- URL: `/api/members/family`403- 方法: `GET`404- 请求头: `Authorization: Bearer <token>`405- 查询参数: `familyId=1`406407**响应**408- 状态码: `200 OK`409- 响应体:410 ```json411 [412 {413 "id": 1,414 "name": "张三",415 "gender": "MALE",416 "birthDate": "1980-01-01",417 "deathDate": null,418 "photo": "https://example.com/photo.jpg",419 "details": "这是成员详情",420 "familyId": 1,421 "createdAt": "2024-01-01T00:00:00"422 }423 ]424 ```425426#### 3.3.3 获取成员详情427428**请求**429- URL: `/api/members/{id}`430- 方法: `GET`431- 请求头: `Authorization: Bearer <token>`432433**响应**434- 状态码: `200 OK`435- 响应体:436 ```json437 {438 "id": 1,439 "name": "张三",440 "gender": "MALE",441 "birthDate": "1980-01-01",442 "deathDate": null,443 "photo": "https://example.com/photo.jpg",444 "details": "这是成员详情",445 "familyId": 1,446 "createdAt": "2024-01-01T00:00:00"447 }448 ```449450#### 3.3.4 更新成员451452**请求**453- URL: `/api/members/{id}`454- 方法: `PUT`455- 请求头: `Authorization: Bearer <token>`456- 内容类型: `application/json`457- 请求体:458 ```json459 {460 "name": "张三(更新)",461 "gender": "MALE",462 "birthDate": "1980-01-01",463 "deathDate": null,464 "photo": "https://example.com/new-photo.jpg",465 "details": "更新后的成员详情"466 }467 ```468469**响应**470- 状态码: `200 OK`471- 响应体:472 ```json473 {474 "id": 1,475 "name": "张三(更新)",476 "gender": "MALE",477 "birthDate": "1980-01-01",478 "deathDate": null,479 "photo": "https://example.com/new-photo.jpg",480 "details": "更新后的成员详情",481 "familyId": 1,482 "createdAt": "2024-01-01T00:00:00"483 }484 ```485486#### 3.3.5 删除成员487488**请求**489- URL: `/api/members/{id}`490- 方法: `DELETE`491- 请求头: `Authorization: Bearer <token>`492493**响应**494- 状态码: `204 No Content`495496### 3.4 关系管理 API497498#### 3.4.1 创建关系499500**请求**501- URL: `/api/relationships`502- 方法: `POST`503- 请求头: `Authorization: Bearer <token>`504- 内容类型: `application/json`505- 请求体:506 ```json507 {508 "memberId1": 1,509 "memberId2": 2,510 "relationshipType": "FATHER"511 }512 ```513514**响应**515- 状态码: `201 Created`516- 响应体:517 ```json518 {519 "id": 1,520 "memberId1": 1,521 "memberId2": 2,522 "relationshipType": "FATHER",523 "createdAt": "2024-01-01T00:00:00"524 }525 ```526527#### 3.4.2 获取关系列表528529**请求**530- URL: `/api/relationships`531- 方法: `GET`532- 请求头: `Authorization: Bearer <token>`533534**响应**535- 状态码: `200 OK`536- 响应体:537 ```json538 [539 {540 "id": 1,541 "memberId1": 1,542 "memberId2": 2,543 "relationshipType": "FATHER",544 "createdAt": "2024-01-01T00:00:00"545 }546 ]547 ```548549#### 3.4.3 获取成员的关系550551**请求**552- URL: `/api/relationships/member`553- 方法: `GET`554- 请求头: `Authorization: Bearer <token>`555- 查询参数: `memberId=1`556557**响应**558- 状态码: `200 OK`559- 响应体:560 ```json561 [562 {563 "id": 1,564 "memberId1": 1,565 "memberId2": 2,566 "relationshipType": "FATHER",567 "createdAt": "2024-01-01T00:00:00"568 }569 ]570 ```571572#### 3.4.4 删除关系573574**请求**575- URL: `/api/relationships/{id}`576- 方法: `DELETE`577- 请求头: `Authorization: Bearer <token>`578579**响应**580- 状态码: `204 No Content`581582### 3.5 事件管理 API583584#### 3.5.1 创建事件585586**请求**587- URL: `/api/events`588- 方法: `POST`589- 请求头: `Authorization: Bearer <token>`590- 内容类型: `application/json`591- 请求体:592 ```json593 {594 "title": "生日派对",595 "description": "张三的生日派对",596 "date": "2024-01-01",597 "location": "家中",598 "familyId": 1599 }600 ```601602**响应**603- 状态码: `201 Created`604- 响应体:605 ```json606 {607 "id": 1,608 "title": "生日派对",609 "description": "张三的生日派对",610 "date": "2024-01-01",611 "location": "家中",612 "familyId": 1,613 "createdAt": "2024-01-01T00:00:00"614 }615 ```616617#### 3.5.2 获取事件列表618619**请求**620- URL: `/api/events`621- 方法: `GET`622- 请求头: `Authorization: Bearer <token>`623624**响应**625- 状态码: `200 OK`626- 响应体:627 ```json628 [629 {630 "id": 1,631 "title": "生日派对",632 "description": "张三的生日派对",633 "date": "2024-01-01",634 "location": "家中",635 "familyId": 1,636 "createdAt": "2024-01-01T00:00:00"637 }638 ]639 ```640641#### 3.5.3 获取事件详情642643**请求**644- URL: `/api/events/{id}`645- 方法: `GET`646- 请求头: `Authorization: Bearer <token>`647648**响应**649- 状态码: `200 OK`650- 响应体:651 ```json652 {653 "id": 1,654 "title": "生日派对",655 "description": "张三的生日派对",656 "date": "2024-01-01",657 "location": "家中",658 "familyId": 1,659 "createdAt": "2024-01-01T00:00:00"660 }661 ```662663#### 3.5.4 更新事件664665**请求**666- URL: `/api/events/{id}`667- 方法: `PUT`668- 请求头: `Authorization: Bearer <token>`669- 内容类型: `application/json`670- 请求体:671 ```json672 {673 "title": "生日派对(更新)",674 "description": "张三的生日派对(更新)",675 "date": "2024-01-02",676 "location": "餐厅",677 "familyId": 1678 }679 ```680681**响应**682- 状态码: `200 OK`683- 响应体:684 ```json685 {686 "id": 1,687 "title": "生日派对(更新)",688 "description": "张三的生日派对(更新)",689 "date": "2024-01-02",690 "location": "餐厅",691 "familyId": 1,692 "createdAt": "2024-01-01T00:00:00"693 }694 ```695696#### 3.5.5 删除事件697698**请求**699- URL: `/api/events/{id}`700- 方法: `DELETE`701- 请求头: `Authorization: Bearer <token>`702703**响应**704- 状态码: `204 No Content`705706### 3.6 媒体管理 API707708#### 3.6.1 上传媒体709710**请求**711- URL: `/api/media`712- 方法: `POST`713- 请求头: `Authorization: Bearer <token>`714- 内容类型: `multipart/form-data`715- 请求体:716 - `file`: 文件717 - `familyId`: 家族ID718 - `description`: 描述719720**响应**721- 状态码: `201 Created`722- 响应体:723 ```json724 {725 "id": 1,726 "fileName": "photo.jpg",727 "filePath": "/uploads/photo.jpg",728 "description": "家族照片",729 "familyId": 1,730 "createdAt": "2024-01-01T00:00:00"731 }732 ```733734#### 3.6.2 获取媒体列表735736**请求**737- URL: `/api/media`738- 方法: `GET`739- 请求头: `Authorization: Bearer <token>`740741**响应**742- 状态码: `200 OK`743- 响应体:744 ```json745 [746 {747 "id": 1,748 "fileName": "photo.jpg",749 "filePath": "/uploads/photo.jpg",750 "description": "家族照片",751 "familyId": 1,752 "createdAt": "2024-01-01T00:00:00"753 }754 ]755 ```756757#### 3.6.3 获取媒体详情758759**请求**760- URL: `/api/media/{id}`761- 方法: `GET`762- 请求头: `Authorization: Bearer <token>`763764**响应**765- 状态码: `200 OK`766- 响应体:767 ```json768 {769 "id": 1,770 "fileName": "photo.jpg",771 "filePath": "/uploads/photo.jpg",772 "description": "家族照片",773 "familyId": 1,774 "createdAt": "2024-01-01T00:00:00"775 }776 ```777778#### 3.6.4 删除媒体779780**请求**781- URL: `/api/media/{id}`782- 方法: `DELETE`783- 请求头: `Authorization: Bearer <token>`784785**响应**786- 状态码: `204 No Content`787788### 3.7 权限管理 API789790#### 3.7.1 分配权限791792**请求**793- URL: `/api/permissions`794- 方法: `POST`795- 请求头: `Authorization: Bearer <token>`796- 内容类型: `application/json`797- 请求体:798 ```json799 {800 "userId": 2,801 "familyId": 1,802 "role": "MEMBER"803 }804 ```805806**响应**807- 状态码: `201 Created`808- 响应体:809 ```json810 {811 "id": 1,812 "userId": 2,813 "familyId": 1,814 "role": "MEMBER",815 "createdAt": "2024-01-01T00:00:00"816 }817 ```818819#### 3.7.2 获取权限列表820821**请求**822- URL: `/api/permissions`823- 方法: `GET`824- 请求头: `Authorization: Bearer <token>`825826**响应**827- 状态码: `200 OK`828- 响应体:829 ```json830 [831 {832 "id": 1,833 "userId": 2,834 "familyId": 1,835 "role": "MEMBER",836 "createdAt": "2024-01-01T00:00:00"837 }838 ]839 ```840841#### 3.7.3 更新权限842843**请求**844- URL: `/api/permissions/{id}`845- 方法: `PUT`846- 请求头: `Authorization: Bearer <token>`847- 内容类型: `application/json`848- 请求体:849 ```json850 {851 "role": "ADMIN"852 }853 ```854855**响应**856- 状态码: `200 OK`857- 响应体:858 ```json859 {860 "id": 1,861 "userId": 2,862 "familyId": 1,863 "role": "ADMIN",864 "createdAt": "2024-01-01T00:00:00"865 }866 ```867868#### 3.7.4 删除权限869870**请求**871- URL: `/api/permissions/{id}`872- 方法: `DELETE`873- 请求头: `Authorization: Bearer <token>`874875**响应**876- 状态码: `204 No Content`877878## 4. 前端与后端交互示例879880### 4.1 登录流程881882```javascript883// 前端登录请求884async function login(email, password) {885 const response = await fetch('http://localhost:8080/api/auth/login', {886 method: 'POST',887 headers: {888 'Content-Type': 'application/json'889 },890 body: JSON.stringify({ email, password })891 });892 893 if (!response.ok) {894 throw new Error('登录失败');895 }896 897 const data = await response.json();898 localStorage.setItem('token', data.token);899 return data;900}901```902903### 4.2 获取家族列表904905```javascript906// 前端获取家族列表907async function getFamilies() {908 const token = localStorage.getItem('token');909 const response = await fetch('http://localhost:8080/api/families', {910 method: 'GET',911 headers: {912 'Authorization': `Bearer ${token}`913 }914 });915 916 if (!response.ok) {917 throw new Error('获取家族列表失败');918 }919 920 return await response.json();921}922```923924### 4.3 添加成员925926```javascript927// 前端添加成员928async function addMember(memberData) {929 const token = localStorage.getItem('token');930 const response = await fetch('http://localhost:8080/api/members', {931 method: 'POST',932 headers: {933 'Content-Type': 'application/json',934 'Authorization': `Bearer ${token}`935 },936 body: JSON.stringify(memberData)937 });938 939 if (!response.ok) {940 throw new Error('添加成员失败');941 }942 943 return await response.json();944}945```946947## 5. 错误处理948949### 5.1 常见错误状态码950951| 状态码 | 描述 | 处理方式 |952|--------|------|----------|953| 400 | 请求参数错误 | 检查请求参数格式是否正确 |954| 401 | 未授权 | 重新登录获取新的token |955| 403 | 禁止访问 | 检查用户是否有相应权限 |956| 404 | 资源不存在 | 检查请求的资源ID是否正确 |957| 500 | 服务器内部错误 | 联系后端开发人员 |958959### 5.2 错误处理示例960961```javascript962// 前端错误处理示例963try {964 const data = await login(email, password);965 // 处理成功逻辑966} catch (error) {967 console.error('登录失败:', error.message);968 // 显示错误提示969}970```971972## 6. API版本管理973974### 6.1 版本控制策略975- **URL路径版本**:`/api/v1/resource`976- **头部版本**:`Accept: application/vnd.familytree.v1+json`977- **查询参数版本**:`/api/resource?version=1`978979### 6.2 版本迁移策略980- 向后兼容:新版本应兼容旧版本API981- 弃用通知:提前通知API弃用计划982- 版本生命周期:明确每个版本的支持期限983984## 7. API安全985986### 7.1 认证与授权987- 使用JWT进行身份认证988- 基于角色的访问控制(RBAC)989- 权限验证中间件990991### 7.2 安全最佳实践992- HTTPS传输993- 输入验证994- 速率限制995- 防止SQL注入996- 防止XSS攻击997- 防止CSRF攻击998999## 8. API监控与分析10001001### 8.1 监控指标1002- 请求响应时间1003- 错误率1004- 并发请求数1005- 资源使用情况10061007### 8.2 分析工具1008- Spring Boot Actuator1009- Prometheus + Grafana1010- ELK Stack(Elasticsearch, Logstash, Kibana)10111012## 9. 最佳实践101310141. **使用HTTPS**:在生产环境中使用HTTPS协议保护API通信10152. **合理使用缓存**:对于不经常变化的数据,可以使用缓存减少API调用10163. **分页处理**:对于大量数据的API,使用分页参数减少数据传输量10174. **错误处理**:对所有API调用进行错误处理,确保用户体验10185. **参数验证**:在前端对用户输入进行验证,减少无效请求10196. **token管理**:合理管理token的存储和刷新,确保安全性10207. **API文档**:使用Swagger等工具自动生成API文档10218. **版本控制**:合理管理API版本,确保向后兼容性10229. **监控**:实现API监控,及时发现和解决问题102310. **测试**:为API编写单元测试和集成测试10241025## 10. 检查清单10261027在开发新的API接口时,请检查以下内容:10281029- [ ] 所有参数都没有直接放在URL路径中(除了资源ID)1030- [ ] GET请求使用查询参数传递参数1031- [ ] POST/PUT请求使用请求体传递参数1032- [ ] 资源ID(如/members/{id})可以放在URL路径中1033- [ ] API契约文档已经更新1034- [ ] 前端和后端实现保持一致1035- [ ] API有适当的错误处理1036- [ ] API有适当的安全措施1037- [ ] API有适当的监控机制1038- [ ] API有适当的测试覆盖10391040## 11. 规范执行10411042所有新开发的API接口必须严格遵守本规范。对于已有的不符合规范的接口,应在后续的迭代中逐步重构,以保持代码库的一致性。10431044## 12. 总结10451046本API管理规范提供了全面的API设计、实现和管理指南,包括:1047- API设计规范:统一参数传递方式,提高代码可读性和安全性1048- API契约定义:详细的API接口文档,便于前后端开发协作1049- 错误处理:统一的错误处理机制,提高用户体验1050- 安全措施:全面的API安全最佳实践1051- 监控与分析:API性能监控和问题排查1052- 最佳实践:行业标准的API开发规范10531054通过遵循本规范,开发者可以构建高质量、可维护、安全的API服务,为家族树应用提供可靠的后端支持。