32 KiB
32 KiB
摄影作品集网站 - API接口设计文档
1. API 概述
1.1 设计原则
- RESTful 设计: 遵循 REST 架构风格
- 统一响应格式: 标准化的 JSON 响应结构
- 版本控制: API 版本化管理
- 安全认证: JWT 令牌认证机制
- 错误处理: 详细的错误码和错误信息
- 性能优化: 支持分页、筛选、排序
1.2 基础信息
Base URL: https://api.photography.iriver.top
API Version: v1
Content-Type: application/json
Authentication: Bearer Token (JWT)
1.3 通用响应格式
1.3.1 成功响应
{
"success": true,
"code": 200,
"message": "Success",
"data": {
// 具体数据内容
},
"meta": {
"timestamp": "2024-01-15T10:30:00Z",
"request_id": "req_123456789"
}
}
1.3.2 分页响应
{
"success": true,
"code": 200,
"message": "Success",
"data": [
// 数据列表
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"total_pages": 8,
"has_next": true,
"has_prev": false
},
"meta": {
"timestamp": "2024-01-15T10:30:00Z",
"request_id": "req_123456789"
}
}
1.3.3 错误响应
{
"success": false,
"code": 400,
"message": "Bad Request",
"error": {
"type": "VALIDATION_ERROR",
"details": [
{
"field": "title",
"message": "Title is required"
}
]
},
"meta": {
"timestamp": "2024-01-15T10:30:00Z",
"request_id": "req_123456789"
}
}
1.4 HTTP 状态码规范
| 状态码 | 说明 | 使用场景 |
|---|---|---|
| 200 | OK | 请求成功 |
| 201 | Created | 资源创建成功 |
| 204 | No Content | 删除成功 |
| 400 | Bad Request | 请求参数错误 |
| 401 | Unauthorized | 未认证 |
| 403 | Forbidden | 权限不足 |
| 404 | Not Found | 资源不存在 |
| 409 | Conflict | 资源冲突 |
| 422 | Unprocessable Entity | 数据验证失败 |
| 429 | Too Many Requests | 请求过于频繁 |
| 500 | Internal Server Error | 服务器内部错误 |
2. 认证与授权
2.1 认证机制
2.1.1 登录认证
POST /v1/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "password123"
}
响应:
{
"success": true,
"code": 200,
"message": "Login successful",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400,
"user": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"display_name": "管理员",
"avatar_url": "https://example.com/avatar.jpg"
}
}
}
2.1.2 令牌刷新
POST /v1/auth/refresh
Content-Type: application/json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
2.1.3 登出
POST /v1/auth/logout
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
2.1.4 用户信息
GET /v1/auth/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
2.2 权限控制
2.2.1 权限级别
{
"roles": {
"super_admin": {
"name": "超级管理员",
"permissions": ["*"]
},
"admin": {
"name": "管理员",
"permissions": [
"photo.*",
"category.*",
"tag.*",
"user.read",
"user.update",
"settings.*"
]
},
"editor": {
"name": "编辑者",
"permissions": [
"photo.read",
"photo.create",
"photo.update",
"category.read",
"tag.read",
"tag.create"
]
},
"user": {
"name": "普通用户",
"permissions": [
"photo.read",
"category.read",
"tag.read"
]
}
}
}
3. 照片管理 API
3.1 照片列表
3.1.1 获取照片列表
GET /v1/photos?page=1&limit=20&status=published&category=1&tag=nature&search=sunset&sort_by=created_at&sort_order=desc
查询参数:
| 参数 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| page | integer | 否 | 页码,默认1 | 1 |
| limit | integer | 否 | 每页数量,默认20 | 20 |
| status | string | 否 | 状态筛选 | published, draft, archived |
| category | integer | 否 | 分类ID | 1 |
| tag | string | 否 | 标签名称 | nature |
| search | string | 否 | 搜索关键词 | sunset |
| sort_by | string | 否 | 排序字段 | created_at, taken_at, title |
| sort_order | string | 否 | 排序方向 | asc, desc |
| year | integer | 否 | 年份筛选 | 2024 |
| month | integer | 否 | 月份筛选 | 1 |
响应:
{
"success": true,
"code": 200,
"data": [
{
"id": 1,
"title": "城市夜景",
"description": "繁华都市的夜晚景色",
"slug": "city-night-view-001",
"status": "published",
"visibility": "public",
"taken_at": "2024-01-15T18:30:00Z",
"created_at": "2024-01-15T20:00:00Z",
"updated_at": "2024-01-15T20:00:00Z",
"view_count": 156,
"like_count": 23,
"formats": {
"thumb_small": "https://cdn.example.com/photos/1/thumb_small.jpg",
"thumb_medium": "https://cdn.example.com/photos/1/thumb_medium.jpg",
"thumb_large": "https://cdn.example.com/photos/1/thumb_large.jpg",
"display": "https://cdn.example.com/photos/1/display.jpg",
"webp": "https://cdn.example.com/photos/1/display.webp"
},
"exif": {
"camera": "Canon EOS R5",
"lens": "RF 24-70mm f/2.8L IS USM",
"iso": 800,
"aperture": "f/2.8",
"shutter_speed": "1/125",
"focal_length": "50mm"
},
"location": {
"name": "上海外滩",
"latitude": 31.23037,
"longitude": 121.47370,
"country": "China",
"city": "Shanghai"
},
"categories": [
{
"id": 1,
"name": "城市风光",
"slug": "cityscape",
"color": "#3498db"
}
],
"tags": [
{
"id": 1,
"name": "夜景",
"slug": "night-view",
"color": "#2c3e50"
},
{
"id": 2,
"name": "城市",
"slug": "city",
"color": "#e74c3c"
}
]
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"total_pages": 8,
"has_next": true,
"has_prev": false
}
}
3.2 照片详情
3.2.1 获取照片详情
GET /v1/photos/{id}
路径参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | integer | 是 | 照片ID |
响应:
{
"success": true,
"code": 200,
"data": {
"id": 1,
"title": "城市夜景",
"description": "繁华都市的夜晚景色,灯火通明的建筑群构成了美丽的天际线...",
"slug": "city-night-view-001",
"status": "published",
"visibility": "public",
"sort_order": 0,
"taken_at": "2024-01-15T18:30:00Z",
"created_at": "2024-01-15T20:00:00Z",
"updated_at": "2024-01-15T20:00:00Z",
"view_count": 156,
"like_count": 23,
"download_count": 5,
"file_info": {
"original_filename": "DSC_0001.jpg",
"file_size": 2048576,
"mime_type": "image/jpeg"
},
"formats": {
"original": "https://cdn.example.com/photos/1/original.jpg",
"jpg": "https://cdn.example.com/photos/1/display.jpg",
"webp": "https://cdn.example.com/photos/1/display.webp",
"thumb_small": "https://cdn.example.com/photos/1/thumb_small.jpg",
"thumb_medium": "https://cdn.example.com/photos/1/thumb_medium.jpg",
"thumb_large": "https://cdn.example.com/photos/1/thumb_large.jpg"
},
"exif": {
"camera": "Canon EOS R5",
"lens": "RF 24-70mm f/2.8L IS USM",
"iso": 800,
"aperture": "f/2.8",
"shutter_speed": "1/125",
"focal_length": "50mm"
},
"location": {
"name": "上海外滩",
"latitude": 31.23037,
"longitude": 121.47370,
"country": "China",
"city": "Shanghai"
},
"categories": [
{
"id": 1,
"name": "城市风光",
"slug": "cityscape",
"description": "城市景观摄影作品",
"color": "#3498db",
"is_primary": true
}
],
"tags": [
{
"id": 1,
"name": "夜景",
"slug": "night-view",
"color": "#2c3e50",
"confidence": 1.0,
"source": "manual"
},
{
"id": 2,
"name": "城市",
"slug": "city",
"color": "#e74c3c",
"confidence": 0.95,
"source": "ai"
}
],
"metadata": {
"weather": "clear",
"temperature": "15°C",
"processing_notes": "调整了曝光和对比度"
}
}
}
3.3 照片操作
3.3.1 创建照片 (用于上传后的元数据创建)
POST /v1/photos
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "城市夜景",
"description": "繁华都市的夜晚景色",
"file_id": "upload_123456789",
"status": "published",
"visibility": "public",
"taken_at": "2024-01-15T18:30:00Z",
"location": {
"name": "上海外滩",
"latitude": 31.23037,
"longitude": 121.47370
},
"categories": [1, 2],
"tags": ["夜景", "城市", "建筑"],
"metadata": {
"weather": "clear",
"temperature": "15°C"
}
}
3.3.2 更新照片信息
PUT /v1/photos/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "上海外滩夜景",
"description": "更新后的描述",
"status": "published",
"categories": [1, 3],
"tags": ["夜景", "城市", "外滩"]
}
3.3.3 删除照片
DELETE /v1/photos/{id}
Authorization: Bearer {token}
3.3.4 批量操作
POST /v1/photos/batch
Authorization: Bearer {token}
Content-Type: application/json
{
"photo_ids": [1, 2, 3, 4, 5],
"action": "update_status",
"data": {
"status": "published"
}
}
支持的批量操作:
update_status: 批量更新状态add_tags: 批量添加标签remove_tags: 批量移除标签add_categories: 批量添加分类remove_categories: 批量移除分类delete: 批量删除
3.4 照片搜索
3.4.1 全文搜索
GET /v1/photos/search?q=夜景&category=1&tags=城市,建筑&location=上海&date_from=2024-01-01&date_to=2024-12-31
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| q | string | 是 | 搜索关键词 |
| category | integer | 否 | 分类ID |
| tags | string | 否 | 标签名称,逗号分隔 |
| location | string | 否 | 地点名称 |
| date_from | string | 否 | 开始日期 (YYYY-MM-DD) |
| date_to | string | 否 | 结束日期 (YYYY-MM-DD) |
| camera | string | 否 | 相机型号 |
| lens | string | 否 | 镜头型号 |
响应:
{
"success": true,
"code": 200,
"data": {
"photos": [
{
"id": 1,
"title": "城市夜景",
"score": 0.95,
"highlight": {
"title": "<mark>夜景</mark>",
"description": "繁华都市的<mark>夜晚</mark>景色"
}
}
],
"facets": {
"categories": [
{"name": "城市风光", "count": 15},
{"name": "建筑摄影", "count": 8}
],
"tags": [
{"name": "夜景", "count": 12},
{"name": "城市", "count": 20}
],
"years": [
{"year": 2024, "count": 25},
{"year": 2023, "count": 18}
]
}
},
"pagination": {
"page": 1,
"limit": 20,
"total": 25
}
}
4. 文件上传 API
4.1 文件上传
4.1.1 单文件上传
POST /v1/upload/single
Authorization: Bearer {token}
Content-Type: multipart/form-data
file: (binary data)
响应:
{
"success": true,
"code": 201,
"data": {
"file_id": "upload_123456789",
"original_filename": "DSC_0001.jpg",
"file_size": 2048576,
"mime_type": "image/jpeg",
"upload_url": "https://temp.example.com/upload_123456789.jpg",
"status": "uploaded",
"exif_extracted": true,
"processing_status": "pending"
}
}
4.1.2 多文件上传
POST /v1/upload/multiple
Authorization: Bearer {token}
Content-Type: multipart/form-data
files[]: (binary data)
files[]: (binary data)
...
响应:
{
"success": true,
"code": 201,
"data": {
"uploaded": [
{
"file_id": "upload_123456789",
"original_filename": "DSC_0001.jpg",
"file_size": 2048576,
"status": "uploaded"
}
],
"failed": [
{
"filename": "invalid_file.txt",
"error": "Invalid file type"
}
],
"summary": {
"total": 5,
"success": 4,
"failed": 1
}
}
}
4.1.3 分块上传
POST /v1/upload/chunked/init
Authorization: Bearer {token}
Content-Type: application/json
{
"filename": "large_photo.raw",
"file_size": 52428800,
"mime_type": "image/raw",
"chunk_size": 1048576
}
响应:
{
"success": true,
"code": 201,
"data": {
"upload_id": "chunked_123456789",
"chunk_size": 1048576,
"total_chunks": 50,
"upload_urls": [
"https://temp.example.com/chunked_123456789/chunk_0",
"https://temp.example.com/chunked_123456789/chunk_1"
]
}
}
4.1.4 上传状态查询
GET /v1/upload/status/{file_id}
Authorization: Bearer {token}
响应:
{
"success": true,
"code": 200,
"data": {
"file_id": "upload_123456789",
"status": "processing",
"progress": 75,
"current_step": "generating_thumbnails",
"steps": [
{"name": "uploaded", "status": "completed"},
{"name": "exif_extraction", "status": "completed"},
{"name": "generating_thumbnails", "status": "processing"},
{"name": "optimization", "status": "pending"}
],
"estimated_time_remaining": 30
}
}
4.2 文件处理
4.2.1 重新处理文件
POST /v1/upload/{file_id}/reprocess
Authorization: Bearer {token}
Content-Type: application/json
{
"formats": ["thumb_small", "thumb_medium", "webp"],
"force": true
}
4.2.2 删除上传文件
DELETE /v1/upload/{file_id}
Authorization: Bearer {token}
5. 分类管理 API
5.1 分类操作
5.1.1 获取分类列表
GET /v1/categories?include_stats=true&include_tree=true
响应:
{
"success": true,
"code": 200,
"data": {
"categories": [
{
"id": 1,
"name": "城市风光",
"slug": "cityscape",
"description": "城市景观摄影作品",
"parent_id": null,
"level": 0,
"path": "1",
"cover_photo": {
"id": 15,
"title": "都市夜景",
"thumb_url": "https://cdn.example.com/photos/15/thumb_medium.jpg"
},
"color": "#3498db",
"icon": "building",
"sort_order": 1,
"is_active": true,
"is_featured": true,
"photo_count": 45,
"direct_photo_count": 30,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"tree": [
{
"id": 1,
"name": "城市风光",
"slug": "cityscape",
"photo_count": 45,
"children": [
{
"id": 2,
"name": "夜景摄影",
"slug": "night-photography",
"photo_count": 15,
"children": []
},
{
"id": 3,
"name": "建筑摄影",
"slug": "architecture",
"photo_count": 30,
"children": []
}
]
}
],
"stats": {
"total_categories": 12,
"max_level": 3,
"featured_count": 5
}
}
}
5.1.2 获取分类详情
GET /v1/categories/{id}
5.1.3 创建分类
POST /v1/categories
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "自然风景",
"slug": "nature-landscape",
"description": "自然风景摄影作品",
"parent_id": null,
"color": "#27ae60",
"icon": "tree",
"sort_order": 2,
"is_featured": true,
"seo_title": "自然风景摄影作品集",
"seo_description": "欣赏美丽的自然风景摄影作品"
}
5.1.4 更新分类
PUT /v1/categories/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "自然风光",
"description": "更新后的描述",
"color": "#2ecc71"
}
5.1.5 删除分类
DELETE /v1/categories/{id}
Authorization: Bearer {token}
5.1.6 设置分类封面
PUT /v1/categories/{id}/cover
Authorization: Bearer {token}
Content-Type: application/json
{
"photo_id": 15
}
5.2 分类照片管理
5.2.1 获取分类下的照片
GET /v1/categories/{id}/photos?page=1&limit=20&sort_by=created_at&sort_order=desc
5.2.2 添加照片到分类
POST /v1/categories/{id}/photos
Authorization: Bearer {token}
Content-Type: application/json
{
"photo_ids": [1, 2, 3],
"is_primary": true
}
5.2.3 从分类移除照片
DELETE /v1/categories/{id}/photos
Authorization: Bearer {token}
Content-Type: application/json
{
"photo_ids": [1, 2, 3]
}
6. 标签管理 API
6.1 标签操作
6.1.1 获取标签列表
GET /v1/tags?group=all&sort_by=usage_count&sort_order=desc&limit=50
响应:
{
"success": true,
"code": 200,
"data": [
{
"id": 1,
"name": "夜景",
"slug": "night-view",
"description": "夜晚拍摄的景色",
"color": "#2c3e50",
"icon": "moon",
"tag_group": "style",
"usage_count": 45,
"trend_score": 8.5,
"is_active": true,
"is_featured": true,
"created_at": "2024-01-01T00:00:00Z",
"last_used_at": "2024-01-15T10:30:00Z"
}
],
"groups": {
"style": {"name": "摄影风格", "count": 12},
"subject": {"name": "拍摄主题", "count": 18},
"technique": {"name": "拍摄技法", "count": 8},
"location": {"name": "地理位置", "count": 25}
}
}
6.1.2 标签搜索建议
GET /v1/tags/suggestions?q=夜&limit=10
响应:
{
"success": true,
"code": 200,
"data": [
{
"id": 1,
"name": "夜景",
"slug": "night-view",
"usage_count": 45,
"match_score": 0.95
},
{
"id": 15,
"name": "夜市",
"slug": "night-market",
"usage_count": 12,
"match_score": 0.8
}
]
}
6.1.3 创建标签
POST /v1/tags
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "极光",
"slug": "aurora",
"description": "极光摄影作品",
"color": "#9b59b6",
"tag_group": "subject",
"is_featured": true
}
6.1.4 更新标签
PUT /v1/tags/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "北极光",
"description": "更新后的描述",
"color": "#8e44ad"
}
6.1.5 删除标签
DELETE /v1/tags/{id}
Authorization: Bearer {token}
6.2 标签统计
6.2.1 标签云数据
GET /v1/tags/cloud?min_usage=5&max_tags=50
响应:
{
"success": true,
"code": 200,
"data": [
{
"id": 1,
"name": "夜景",
"usage_count": 45,
"relative_size": 100,
"color": "#2c3e50"
},
{
"id": 2,
"name": "城市",
"usage_count": 38,
"relative_size": 84,
"color": "#e74c3c"
}
]
}
6.2.2 趋势标签
GET /v1/tags/trending?period=30d&limit=10
7. 时间线 API
7.1 时间线数据
7.1.1 获取时间线
GET /v1/timeline?year=2024&include_photos=true&photos_limit=5
响应:
{
"success": true,
"code": 200,
"data": {
"years": [
{
"year": 2024,
"photo_count": 156,
"months": [
{
"month": 1,
"month_name": "一月",
"photo_count": 25,
"photos": [
{
"id": 1,
"title": "城市夜景",
"thumb_url": "https://cdn.example.com/photos/1/thumb_medium.jpg",
"taken_at": "2024-01-15T18:30:00Z"
}
],
"events": [
{
"id": 1,
"title": "首次夜景拍摄",
"description": "第一次尝试城市夜景摄影",
"date": "2024-01-15",
"type": "milestone"
}
]
}
]
}
],
"stats": {
"total_photos": 456,
"year_range": [2020, 2024],
"most_active_month": {
"year": 2024,
"month": 3,
"count": 45
},
"photos_by_year": [
{"year": 2024, "count": 156},
{"year": 2023, "count": 189},
{"year": 2022, "count": 111}
]
}
}
}
7.1.2 获取指定月份详情
GET /v1/timeline/{year}/{month}?include_photos=true
7.2 时间线事件
7.2.1 创建事件
POST /v1/timeline/events
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "获得摄影比赛奖项",
"description": "在城市摄影大赛中获得金奖",
"date": "2024-03-15",
"type": "achievement",
"related_photos": [15, 23, 31]
}
7.2.2 更新事件
PUT /v1/timeline/events/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "更新后的标题",
"description": "更新后的描述"
}
7.2.3 删除事件
DELETE /v1/timeline/events/{id}
Authorization: Bearer {token}
8. 系统设置 API
8.1 设置管理
8.1.1 获取系统设置
GET /v1/settings?category=all&include_public=true
响应:
{
"success": true,
"code": 200,
"data": {
"general": {
"site_title": "摄影作品集",
"site_description": "专业摄影师作品展示平台",
"site_keywords": "摄影,作品集,艺术,创作",
"site_author": "摄影师姓名",
"site_email": "contact@example.com"
},
"upload": {
"max_file_size": 52428800,
"allowed_types": ["image/jpeg", "image/png", "image/raw"],
"max_files_per_batch": 50,
"auto_publish": false,
"generate_thumbnails": true
},
"image": {
"quality_jpg": 85,
"quality_webp": 80,
"max_width": 1920,
"max_height": 1080,
"watermark_enabled": false
},
"display": {
"photos_per_page": 20,
"thumbnail_size": 300,
"theme_primary_color": "#d4af37",
"theme_secondary_color": "#2d2d2d",
"enable_dark_mode": true,
"enable_animations": true
}
}
}
8.1.2 更新系统设置
PUT /v1/settings
Authorization: Bearer {token}
Content-Type: application/json
{
"site_title": "我的摄影作品集",
"upload_max_file_size": 104857600,
"display_photos_per_page": 24
}
8.1.3 重置设置
POST /v1/settings/reset
Authorization: Bearer {token}
Content-Type: application/json
{
"categories": ["upload", "image"],
"confirm": true
}
8.2 缓存管理
8.2.1 清理缓存
POST /v1/settings/cache/clear
Authorization: Bearer {token}
Content-Type: application/json
{
"types": ["photos", "categories", "tags", "settings"],
"confirm": true
}
8.2.2 预热缓存
POST /v1/settings/cache/warm
Authorization: Bearer {token}
Content-Type: application/json
{
"types": ["popular_photos", "category_tree", "tag_cloud"]
}
8.2.3 缓存统计
GET /v1/settings/cache/stats
Authorization: Bearer {token}
响应:
{
"success": true,
"code": 200,
"data": {
"redis": {
"connected": true,
"used_memory": "15.2MB",
"total_keys": 1247,
"hit_rate": 0.89
},
"categories": {
"photos": {"keys": 456, "hit_rate": 0.92},
"categories": {"keys": 12, "hit_rate": 0.95},
"tags": {"keys": 89, "hit_rate": 0.87},
"settings": {"keys": 1, "hit_rate": 0.99}
}
}
}
9. 统计分析 API
9.1 仪表板统计
9.1.1 仪表板数据
GET /v1/dashboard/stats?period=30d
响应:
{
"success": true,
"code": 200,
"data": {
"summary": {
"total_photos": 456,
"total_categories": 12,
"total_tags": 89,
"total_views": 15420,
"storage_used": 2684354560,
"storage_limit": 10737418240
},
"recent": {
"new_photos": 15,
"new_views": 234,
"new_likes": 67,
"period": "7d"
},
"trends": {
"uploads": [
{"date": "2024-01-01", "count": 5},
{"date": "2024-01-02", "count": 8},
{"date": "2024-01-03", "count": 3}
],
"views": [
{"date": "2024-01-01", "count": 156},
{"date": "2024-01-02", "count": 234},
{"date": "2024-01-03", "count": 189}
]
},
"popular": {
"categories": [
{"name": "城市风光", "count": 45, "percentage": 28.5},
{"name": "自然风景", "count": 38, "percentage": 24.1}
],
"tags": [
{"name": "夜景", "count": 45},
{"name": "城市", "count": 38}
],
"photos": [
{
"id": 15,
"title": "都市夜景",
"view_count": 1247,
"like_count": 89
}
]
},
"system_status": {
"database": "healthy",
"redis": "healthy",
"storage": "healthy",
"queue": "healthy"
}
}
}
9.2 详细统计
9.2.1 照片统计
GET /v1/stats/photos?group_by=month&year=2024
9.2.2 访问统计
GET /v1/stats/views?period=30d&group_by=day
9.2.3 存储统计
GET /v1/stats/storage
10. 用户管理 API
10.1 用户操作
10.1.1 获取用户列表
GET /v1/users?page=1&limit=20&role=all&status=active&search=admin
10.1.2 创建用户
POST /v1/users
Authorization: Bearer {token}
Content-Type: application/json
{
"username": "editor",
"email": "editor@example.com",
"password": "password123",
"role": "editor",
"display_name": "编辑者",
"is_active": true
}
10.1.3 更新用户
PUT /v1/users/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"display_name": "高级编辑者",
"role": "admin",
"is_active": true
}
10.1.4 删除用户
DELETE /v1/users/{id}
Authorization: Bearer {token}
10.2 用户会话管理
10.2.1 获取用户会话
GET /v1/users/{id}/sessions
Authorization: Bearer {token}
10.2.2 强制下线
DELETE /v1/users/{id}/sessions/{session_id}
Authorization: Bearer {token}
11. 错误处理
11.1 错误码定义
| 错误码 | HTTP状态码 | 说明 |
|---|---|---|
| VALIDATION_ERROR | 400 | 请求参数验证失败 |
| AUTHENTICATION_REQUIRED | 401 | 需要认证 |
| INVALID_TOKEN | 401 | 无效的令牌 |
| TOKEN_EXPIRED | 401 | 令牌已过期 |
| PERMISSION_DENIED | 403 | 权限不足 |
| RESOURCE_NOT_FOUND | 404 | 资源不存在 |
| RESOURCE_CONFLICT | 409 | 资源冲突 |
| UNPROCESSABLE_ENTITY | 422 | 数据处理失败 |
| RATE_LIMIT_EXCEEDED | 429 | 请求频率超限 |
| INTERNAL_SERVER_ERROR | 500 | 服务器内部错误 |
| SERVICE_UNAVAILABLE | 503 | 服务不可用 |
11.2 错误响应示例
11.2.1 验证错误
{
"success": false,
"code": 400,
"message": "Validation failed",
"error": {
"type": "VALIDATION_ERROR",
"details": [
{
"field": "title",
"message": "Title is required",
"code": "REQUIRED"
},
{
"field": "email",
"message": "Invalid email format",
"code": "INVALID_FORMAT"
}
]
}
}
11.2.2 权限错误
{
"success": false,
"code": 403,
"message": "Permission denied",
"error": {
"type": "PERMISSION_DENIED",
"details": {
"required_permission": "photo.delete",
"user_role": "editor"
}
}
}
11.2.3 资源不存在
{
"success": false,
"code": 404,
"message": "Resource not found",
"error": {
"type": "RESOURCE_NOT_FOUND",
"details": {
"resource_type": "photo",
"resource_id": 999
}
}
}
12. API 限流
12.1 限流策略
| 端点类型 | 限制 | 时间窗口 |
|---|---|---|
| 认证端点 | 5次/IP | 1分钟 |
| 上传端点 | 10次/用户 | 1分钟 |
| 搜索端点 | 60次/用户 | 1分钟 |
| 一般端点 | 1000次/用户 | 1小时 |
| 管理端点 | 500次/用户 | 1小时 |
12.2 限流响应头
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1642636800
X-RateLimit-Window: 3600
12.3 限流超出响应
{
"success": false,
"code": 429,
"message": "Rate limit exceeded",
"error": {
"type": "RATE_LIMIT_EXCEEDED",
"details": {
"limit": 1000,
"window": 3600,
"reset_at": "2024-01-15T11:00:00Z"
}
}
}
13. WebHook API
13.1 WebHook 配置
13.1.1 创建 WebHook
POST /v1/webhooks
Authorization: Bearer {token}
Content-Type: application/json
{
"url": "https://example.com/webhook",
"events": ["photo.created", "photo.updated", "photo.deleted"],
"secret": "webhook_secret_key",
"is_active": true
}
13.1.2 WebHook 事件类型
| 事件类型 | 描述 | 数据载荷 |
|---|---|---|
| photo.created | 照片创建 | 完整照片数据 |
| photo.updated | 照片更新 | 更新后的照片数据 |
| photo.deleted | 照片删除 | 删除的照片ID |
| category.created | 分类创建 | 完整分类数据 |
| category.updated | 分类更新 | 更新后的分类数据 |
| category.deleted | 分类删除 | 删除的分类ID |
| user.login | 用户登录 | 用户基本信息 |
| system.backup | 系统备份 | 备份状态信息 |
13.2 WebHook 载荷示例
{
"event": "photo.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"id": 1,
"title": "城市夜景",
"status": "published",
"created_at": "2024-01-15T10:30:00Z"
},
"signature": "sha256=abcdef123456..."
}
14. API 版本控制
14.1 版本策略
- URL 版本控制:
/v1/,/v2/ - 向后兼容: 至少支持2个主版本
- 废弃通知: 通过响应头通知
14.2 版本响应头
API-Version: 1.0
API-Deprecated: false
API-Sunset: 2025-01-15T00:00:00Z
14.3 版本变更日志
版本 1.0.0 (当前)
- 初始 API 版本
- 支持照片、分类、标签管理
- 用户认证和权限控制
版本 1.1.0 (计划)
- 添加 AI 标签推荐
- 支持视频文件
- 增强搜索功能
15. 总结
这个API接口设计文档提供了摄影作品集网站的完整API规范,包括:
🎯 设计特点
- RESTful 风格: 符合REST架构原则
- 统一响应格式: 标准化的JSON响应
- 完整的CRUD操作: 支持所有资源的增删改查
- 灵活的查询: 丰富的筛选、排序、搜索功能
🔒 安全机制
- JWT认证: 基于令牌的认证机制
- 权限控制: 细粒度的角色权限管理
- 请求限流: 防止API滥用
- 数据验证: 严格的输入验证
📊 功能丰富
- 文件上传: 支持单文件、多文件、分块上传
- 图片处理: 自动生成多种格式和尺寸
- 全文搜索: 强大的搜索和筛选功能
- 统计分析: 详细的数据统计和趋势分析
🛠️ 开发友好
- 详细文档: 完整的接口说明和示例
- 错误处理: 清晰的错误码和错误信息
- 版本控制: 科学的API版本管理
- WebHook支持: 事件驱动的集成能力
这个API设计为Golang后端实现提供了完整的接口规范,可以支持前端和管理后台的所有功能需求。