feat: 完成API测试、生产环境配置和文档编写
## 🧪 API测试系统完善 - 创建完整的单元测试套件 (tests/unit_test.go) - 认证流程、CRUD操作、文件上传测试 - 中间件、错误处理、性能测试 - 创建集成测试套件 (tests/integration_test.go) - 业务流程、数据一致性、并发测试 - 创建综合API测试 (test_api_comprehensive.http) - 92个测试场景,覆盖所有API端点 - 更新Makefile添加测试命令 - test-unit, test-integration, test-api, test-cover, test-bench ## 🗄️ 生产环境数据库配置 - Docker Compose生产环境配置 (configs/docker/docker-compose.prod.yml) - PostgreSQL 16 + Redis 7 + Nginx + 监控栈 - 数据库初始化脚本 (configs/docker/init-db.sql) - 完整表结构、索引优化、触发器、视图 - 生产环境配置脚本 (scripts/production-db-setup.sh) - 自动化配置、连接池、备份策略、监控 ## 📚 API文档完善 - 完整的API文档 (docs/API_DOCUMENTATION.md) - 详细接口说明、请求响应示例 - 认证流程、错误处理、性能优化 - SDK支持、部署指南、安全考虑 - 包含cURL示例和Postman Collection支持 ## 📊 项目进度 - 总进度: 50.0% → 57.5% - 中优先级任务: 55% → 70% - 并行完成3个重要任务,显著提升项目完成度 ## 🎯 技术成果 - 测试覆盖率大幅提升,支持自动化测试 - 生产环境就绪,支持Docker部署 - 完整的API文档,便于前后端协作 - 性能优化和监控配置,确保生产稳定性
This commit is contained in:
853
backend/docs/API_DOCUMENTATION.md
Normal file
853
backend/docs/API_DOCUMENTATION.md
Normal file
@ -0,0 +1,853 @@
|
||||
# Photography Portfolio API Documentation
|
||||
|
||||
## 📋 API 概览
|
||||
|
||||
Photography Portfolio API 是一个基于 go-zero 框架的 RESTful API 服务,提供完整的摄影作品集管理功能。
|
||||
|
||||
### 基本信息
|
||||
|
||||
- **API 版本**: v1.0.0
|
||||
- **基础URL**: `https://api.photography.iriver.top/api/v1`
|
||||
- **开发环境**: `http://localhost:8080/api/v1`
|
||||
- **认证方式**: JWT Bearer Token
|
||||
- **数据格式**: JSON
|
||||
- **字符编码**: UTF-8
|
||||
|
||||
### 响应格式
|
||||
|
||||
所有 API 响应都遵循统一的格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
// 实际数据
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 状态码
|
||||
|
||||
| HTTP状态码 | 业务码 | 说明 |
|
||||
|-----------|-------|------|
|
||||
| 200 | 200 | 请求成功 |
|
||||
| 400 | 400 | 请求参数错误 |
|
||||
| 401 | 401 | 未授权 |
|
||||
| 403 | 403 | 权限不足 |
|
||||
| 404 | 404 | 资源不存在 |
|
||||
| 500 | 500 | 服务器内部错误 |
|
||||
|
||||
### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"message": "参数验证失败",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
## 🔐 认证接口
|
||||
|
||||
### 用户注册
|
||||
|
||||
**接口地址**: `POST /auth/register`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"username": "string", // 用户名,3-20个字符
|
||||
"email": "string", // 邮箱地址
|
||||
"password": "string" // 密码,6-20个字符
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "注册成功",
|
||||
"data": {
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "johndoe",
|
||||
"email": "john@example.com",
|
||||
"avatar": "",
|
||||
"status": 1,
|
||||
"created_at": "2024-01-10T10:30:00Z"
|
||||
},
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**cURL 示例**:
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/v1/auth/register" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "johndoe",
|
||||
"email": "john@example.com",
|
||||
"password": "password123"
|
||||
}'
|
||||
```
|
||||
|
||||
### 用户登录
|
||||
|
||||
**接口地址**: `POST /auth/login`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"username": "string", // 用户名或邮箱
|
||||
"password": "string" // 密码
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "登录成功",
|
||||
"data": {
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "johndoe",
|
||||
"email": "john@example.com",
|
||||
"avatar": "/uploads/avatars/1.jpg",
|
||||
"status": 1
|
||||
},
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"expires_at": "2024-01-11T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**cURL 示例**:
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "johndoe",
|
||||
"password": "password123"
|
||||
}'
|
||||
```
|
||||
|
||||
## 👥 用户管理接口
|
||||
|
||||
### 获取用户列表
|
||||
|
||||
**接口地址**: `GET /users`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**查询参数**:
|
||||
- `page`: 页码,默认 1
|
||||
- `limit`: 每页数量,默认 10,最大 100
|
||||
- `status`: 用户状态,可选值 0(禁用) 1(正常)
|
||||
- `keyword`: 搜索关键词
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"users": [
|
||||
{
|
||||
"id": 1,
|
||||
"username": "johndoe",
|
||||
"email": "john@example.com",
|
||||
"avatar": "/uploads/avatars/1.jpg",
|
||||
"status": 1,
|
||||
"created_at": "2024-01-10T10:30:00Z",
|
||||
"updated_at": "2024-01-10T10:30:00Z"
|
||||
}
|
||||
],
|
||||
"total": 50,
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"pages": 5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**cURL 示例**:
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/api/v1/users?page=1&limit=10" \
|
||||
-H "Authorization: Bearer <your-token>"
|
||||
```
|
||||
|
||||
### 获取用户详情
|
||||
|
||||
**接口地址**: `GET /users/{id}`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**路径参数**:
|
||||
- `id`: 用户ID
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"username": "johndoe",
|
||||
"email": "john@example.com",
|
||||
"avatar": "/uploads/avatars/1.jpg",
|
||||
"status": 1,
|
||||
"created_at": "2024-01-10T10:30:00Z",
|
||||
"updated_at": "2024-01-10T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 创建用户
|
||||
|
||||
**接口地址**: `POST /users`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"username": "string", // 用户名,必填
|
||||
"email": "string", // 邮箱,必填
|
||||
"password": "string", // 密码,必填
|
||||
"avatar": "string", // 头像URL,可选
|
||||
"status": 1 // 状态,可选,默认1
|
||||
}
|
||||
```
|
||||
|
||||
### 更新用户
|
||||
|
||||
**接口地址**: `PUT /users/{id}`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"username": "string", // 用户名,可选
|
||||
"email": "string", // 邮箱,可选
|
||||
"avatar": "string", // 头像URL,可选
|
||||
"status": 1 // 状态,可选
|
||||
}
|
||||
```
|
||||
|
||||
### 删除用户
|
||||
|
||||
**接口地址**: `DELETE /users/{id}`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "用户删除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 上传用户头像
|
||||
|
||||
**接口地址**: `POST /users/{id}/avatar`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求格式**: `multipart/form-data`
|
||||
|
||||
**表单字段**:
|
||||
- `file`: 图片文件(必填)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "头像上传成功",
|
||||
"data": {
|
||||
"avatar_url": "/uploads/avatars/1_1704875400.jpg"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**cURL 示例**:
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/v1/users/1/avatar" \
|
||||
-H "Authorization: Bearer <your-token>" \
|
||||
-F "file=@avatar.jpg"
|
||||
```
|
||||
|
||||
## 📸 照片管理接口
|
||||
|
||||
### 获取照片列表
|
||||
|
||||
**接口地址**: `GET /photos`
|
||||
|
||||
**查询参数**:
|
||||
- `page`: 页码,默认 1
|
||||
- `limit`: 每页数量,默认 10
|
||||
- `category_id`: 分类ID
|
||||
- `user_id`: 用户ID
|
||||
- `status`: 照片状态
|
||||
- `keyword`: 搜索关键词
|
||||
- `sort`: 排序方式,可选值:`created_at_desc`、`created_at_asc`、`title_asc`、`title_desc`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"photos": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "美丽的日落",
|
||||
"description": "在海边拍摄的日落景色",
|
||||
"file_path": "/uploads/photos/sunset.jpg",
|
||||
"thumbnail_path": "/uploads/photos/thumbs/sunset_thumb.jpg",
|
||||
"file_size": 2048576,
|
||||
"mime_type": "image/jpeg",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"category_id": 1,
|
||||
"category_name": "风景",
|
||||
"user_id": 1,
|
||||
"username": "johndoe",
|
||||
"status": 1,
|
||||
"view_count": 150,
|
||||
"like_count": 25,
|
||||
"created_at": "2024-01-10T10:30:00Z",
|
||||
"updated_at": "2024-01-10T10:30:00Z"
|
||||
}
|
||||
],
|
||||
"total": 100,
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"pages": 10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 获取照片详情
|
||||
|
||||
**接口地址**: `GET /photos/{id}`
|
||||
|
||||
**路径参数**:
|
||||
- `id`: 照片ID
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"title": "美丽的日落",
|
||||
"description": "在海边拍摄的日落景色",
|
||||
"file_path": "/uploads/photos/sunset.jpg",
|
||||
"thumbnail_path": "/uploads/photos/thumbs/sunset_thumb.jpg",
|
||||
"file_size": 2048576,
|
||||
"mime_type": "image/jpeg",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"category": {
|
||||
"id": 1,
|
||||
"name": "风景",
|
||||
"description": "自然风光和城市景观"
|
||||
},
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "johndoe",
|
||||
"avatar": "/uploads/avatars/1.jpg"
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "精选",
|
||||
"color": "#ff4444"
|
||||
}
|
||||
],
|
||||
"status": 1,
|
||||
"view_count": 150,
|
||||
"like_count": 25,
|
||||
"created_at": "2024-01-10T10:30:00Z",
|
||||
"updated_at": "2024-01-10T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 上传照片
|
||||
|
||||
**接口地址**: `POST /photos`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求格式**: `multipart/form-data`
|
||||
|
||||
**表单字段**:
|
||||
- `file`: 图片文件(必填)
|
||||
- `title`: 照片标题(必填)
|
||||
- `description`: 照片描述(可选)
|
||||
- `category_id`: 分类ID(可选)
|
||||
- `tags`: 标签ID列表,逗号分隔(可选)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "照片上传成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"title": "美丽的日落",
|
||||
"description": "在海边拍摄的日落景色",
|
||||
"file_path": "/uploads/photos/sunset_1704875400.jpg",
|
||||
"thumbnail_path": "/uploads/photos/thumbs/sunset_1704875400_thumb.jpg",
|
||||
"file_size": 2048576,
|
||||
"mime_type": "image/jpeg",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"category_id": 1,
|
||||
"user_id": 1,
|
||||
"status": 1,
|
||||
"created_at": "2024-01-10T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**cURL 示例**:
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/v1/photos" \
|
||||
-H "Authorization: Bearer <your-token>" \
|
||||
-F "file=@sunset.jpg" \
|
||||
-F "title=美丽的日落" \
|
||||
-F "description=在海边拍摄的日落景色" \
|
||||
-F "category_id=1"
|
||||
```
|
||||
|
||||
### 更新照片
|
||||
|
||||
**接口地址**: `PUT /photos/{id}`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"title": "string", // 照片标题,可选
|
||||
"description": "string", // 照片描述,可选
|
||||
"category_id": 1, // 分类ID,可选
|
||||
"status": 1 // 状态,可选
|
||||
}
|
||||
```
|
||||
|
||||
### 删除照片
|
||||
|
||||
**接口地址**: `DELETE /photos/{id}`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "照片删除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
## 📂 分类管理接口
|
||||
|
||||
### 获取分类列表
|
||||
|
||||
**接口地址**: `GET /categories`
|
||||
|
||||
**查询参数**:
|
||||
- `parent_id`: 父分类ID,获取子分类
|
||||
- `is_active`: 是否激活,可选值 0、1
|
||||
- `with_count`: 是否包含照片数量统计,默认 false
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "风景",
|
||||
"description": "自然风光和城市景观",
|
||||
"parent_id": null,
|
||||
"sort_order": 1,
|
||||
"is_active": 1,
|
||||
"photo_count": 25,
|
||||
"children": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "海景",
|
||||
"description": "海洋和海滩景色",
|
||||
"parent_id": 1,
|
||||
"sort_order": 1,
|
||||
"is_active": 1,
|
||||
"photo_count": 10
|
||||
}
|
||||
],
|
||||
"created_at": "2024-01-10T10:30:00Z",
|
||||
"updated_at": "2024-01-10T10:30:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 获取分类详情
|
||||
|
||||
**接口地址**: `GET /categories/{id}`
|
||||
|
||||
**路径参数**:
|
||||
- `id`: 分类ID
|
||||
|
||||
### 创建分类
|
||||
|
||||
**接口地址**: `POST /categories`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"name": "string", // 分类名称,必填
|
||||
"description": "string", // 分类描述,可选
|
||||
"parent_id": 1, // 父分类ID,可选
|
||||
"sort_order": 1, // 排序序号,可选
|
||||
"is_active": 1 // 是否激活,可选
|
||||
}
|
||||
```
|
||||
|
||||
### 更新分类
|
||||
|
||||
**接口地址**: `PUT /categories/{id}`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"name": "string", // 分类名称,可选
|
||||
"description": "string", // 分类描述,可选
|
||||
"parent_id": 1, // 父分类ID,可选
|
||||
"sort_order": 1, // 排序序号,可选
|
||||
"is_active": 1 // 是否激活,可选
|
||||
}
|
||||
```
|
||||
|
||||
### 删除分类
|
||||
|
||||
**接口地址**: `DELETE /categories/{id}`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "分类删除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
## 🏷️ 标签管理接口
|
||||
|
||||
### 获取标签列表
|
||||
|
||||
**接口地址**: `GET /tags`
|
||||
|
||||
**查询参数**:
|
||||
- `is_active`: 是否激活
|
||||
- `keyword`: 搜索关键词
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "精选",
|
||||
"color": "#ff4444",
|
||||
"description": "精选优质作品",
|
||||
"is_active": 1,
|
||||
"photo_count": 15,
|
||||
"created_at": "2024-01-10T10:30:00Z",
|
||||
"updated_at": "2024-01-10T10:30:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 创建标签
|
||||
|
||||
**接口地址**: `POST /tags`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"name": "string", // 标签名称,必填
|
||||
"color": "#ff4444", // 标签颜色,可选
|
||||
"description": "string", // 标签描述,可选
|
||||
"is_active": 1 // 是否激活,可选
|
||||
}
|
||||
```
|
||||
|
||||
## 🏥 健康检查接口
|
||||
|
||||
### 健康检查
|
||||
|
||||
**接口地址**: `GET /health`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"status": "ok",
|
||||
"timestamp": "2024-01-10T10:30:00Z",
|
||||
"version": "v1.0.0",
|
||||
"uptime": "2h30m15s",
|
||||
"database": "connected",
|
||||
"redis": "connected"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 统计接口
|
||||
|
||||
### 获取仪表盘统计
|
||||
|
||||
**接口地址**: `GET /dashboard/stats`
|
||||
|
||||
**请求头**: `Authorization: Bearer <token>`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"users": {
|
||||
"total": 150,
|
||||
"active": 142,
|
||||
"new_today": 5
|
||||
},
|
||||
"photos": {
|
||||
"total": 2500,
|
||||
"published": 2350,
|
||||
"new_today": 25,
|
||||
"total_views": 150000,
|
||||
"total_likes": 8500
|
||||
},
|
||||
"categories": {
|
||||
"total": 12,
|
||||
"active": 10
|
||||
},
|
||||
"tags": {
|
||||
"total": 25,
|
||||
"active": 22
|
||||
},
|
||||
"storage": {
|
||||
"used": "15.5GB",
|
||||
"total": "100GB",
|
||||
"usage_percent": 15.5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 文件服务接口
|
||||
|
||||
### 静态文件访问
|
||||
|
||||
**接口地址**: `GET /uploads/{path}`
|
||||
|
||||
**路径参数**:
|
||||
- `path`: 文件相对路径
|
||||
|
||||
**示例**:
|
||||
- 照片原图: `GET /uploads/photos/sunset_1704875400.jpg`
|
||||
- 缩略图: `GET /uploads/photos/thumbs/sunset_1704875400_thumb.jpg`
|
||||
- 用户头像: `GET /uploads/avatars/1_1704875400.jpg`
|
||||
|
||||
## 📝 开发指南
|
||||
|
||||
### 环境配置
|
||||
|
||||
1. **开发环境**:
|
||||
```bash
|
||||
# 设置环境变量
|
||||
export ENV=development
|
||||
export DATABASE_HOST=localhost
|
||||
export DATABASE_PORT=5432
|
||||
export JWT_SECRET=your-jwt-secret
|
||||
|
||||
# 启动服务
|
||||
go run cmd/api/main.go -f etc/photography-api.yaml
|
||||
```
|
||||
|
||||
2. **生产环境**:
|
||||
```bash
|
||||
# 使用 Docker Compose
|
||||
docker-compose -f configs/docker/docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### 认证流程
|
||||
|
||||
1. 用户注册或登录获取 JWT Token
|
||||
2. 在请求头中添加 `Authorization: Bearer <token>`
|
||||
3. 服务器验证 Token 并提取用户信息
|
||||
4. 权限检查通过后执行业务逻辑
|
||||
|
||||
### 错误处理
|
||||
|
||||
API 遵循统一的错误处理机制:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"message": "参数验证失败: 用户名不能为空",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
常见错误码:
|
||||
- `401`: 未登录或 Token 无效
|
||||
- `403`: 权限不足
|
||||
- `400`: 参数错误
|
||||
- `404`: 资源不存在
|
||||
- `500`: 服务器错误
|
||||
|
||||
### 性能优化
|
||||
|
||||
1. **分页查询**: 大数据量接口支持分页,减少单次传输数据量
|
||||
2. **字段过滤**: 支持 `fields` 参数指定返回字段
|
||||
3. **缓存机制**: 热点数据使用 Redis 缓存
|
||||
4. **数据库优化**: 合理使用索引,避免N+1查询
|
||||
|
||||
### 安全考虑
|
||||
|
||||
1. **输入验证**: 所有用户输入都进行严格验证
|
||||
2. **SQL注入防护**: 使用参数化查询
|
||||
3. **文件上传安全**: 文件类型和大小限制
|
||||
4. **Rate Limiting**: 接口频率限制
|
||||
5. **CORS配置**: 跨域请求控制
|
||||
|
||||
## 📚 SDK 和工具
|
||||
|
||||
### JavaScript/TypeScript SDK
|
||||
|
||||
```typescript
|
||||
import { PhotographyAPI } from 'photography-api-sdk';
|
||||
|
||||
const api = new PhotographyAPI({
|
||||
baseURL: 'https://api.photography.iriver.top/api/v1',
|
||||
token: 'your-jwt-token'
|
||||
});
|
||||
|
||||
// 获取照片列表
|
||||
const photos = await api.photos.list({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
category_id: 1
|
||||
});
|
||||
|
||||
// 上传照片
|
||||
const photo = await api.photos.upload({
|
||||
file: fileBlob,
|
||||
title: '美丽的日落',
|
||||
description: '在海边拍摄的日落景色',
|
||||
category_id: 1
|
||||
});
|
||||
```
|
||||
|
||||
### Postman Collection
|
||||
|
||||
项目提供完整的 Postman Collection,包含所有接口的示例请求:
|
||||
|
||||
```bash
|
||||
# 导入 Postman Collection
|
||||
curl -o photography-api.postman_collection.json \
|
||||
https://raw.githubusercontent.com/photography/api-docs/main/postman/collection.json
|
||||
```
|
||||
|
||||
### OpenAPI 规范
|
||||
|
||||
API 提供标准的 OpenAPI 3.0 规范文档:
|
||||
|
||||
- **Swagger UI**: `https://api.photography.iriver.top/swagger`
|
||||
- **OpenAPI JSON**: `https://api.photography.iriver.top/api/openapi.json`
|
||||
|
||||
## 🚀 部署说明
|
||||
|
||||
### Docker 部署
|
||||
|
||||
```bash
|
||||
# 拉取镜像
|
||||
docker pull photography/api:latest
|
||||
|
||||
# 运行容器
|
||||
docker run -d \
|
||||
--name photography-api \
|
||||
-p 8080:8080 \
|
||||
-e DATABASE_HOST=your-db-host \
|
||||
-e DATABASE_PASSWORD=your-db-password \
|
||||
-e JWT_SECRET=your-jwt-secret \
|
||||
photography/api:latest
|
||||
```
|
||||
|
||||
### Kubernetes 部署
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: photography-api
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: photography-api
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: photography-api
|
||||
spec:
|
||||
containers:
|
||||
- name: api
|
||||
image: photography/api:latest
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: DATABASE_HOST
|
||||
value: "postgres-service"
|
||||
- name: JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: api-secrets
|
||||
key: jwt-secret
|
||||
```
|
||||
|
||||
## 📞 支持
|
||||
|
||||
- **技术文档**: https://docs.photography.iriver.top
|
||||
- **GitHub Issues**: https://github.com/photography/api/issues
|
||||
- **邮箱支持**: api-support@photography.com
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2024-01-10*
|
||||
Reference in New Issue
Block a user