# MinIO 存储管理 API 文档
## 概述
MinIO 存储管理模块提供对象存储的完整管理能力,包括存储桶管理和文件操作。
**基础路径**: `/api/v2/storage`
**认证要求**: 当前无需认证(后续可按需添加)
---
## 接口列表
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/buckets` | 创建存储桶 |
| DELETE | `/buckets` | 删除存储桶 |
| GET | `/buckets` | 列出所有存储桶 |
| POST | `/files/copy` | 复制文件 |
| POST | `/files/move` | 移动/重命名文件 |
| DELETE | `/files` | 删除单个文件 |
| POST | `/files/batch-delete` | 批量删除文件 |
| GET | `/files/download` | 下载文件 |
| GET | `/files` | 列出目录文件 |
| GET | `/files/metadata` | 获取文件元数据 |
| GET | `/files/presigned-url` | 获取预签名URL |
---
## 存储桶管理
### 1. 创建存储桶
**POST** `/api/v2/storage/buckets`
创建新的 MinIO 存储桶。
#### 请求体
```json
{
"bucket_name": "my-new-bucket"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| bucket_name | string | 是 | 存储桶名称(3-63字符,小写字母、数字、连字符) |
#### 响应示例
**成功 (200)**
```json
{
"success": true,
"message": "存储桶创建成功",
"bucket_name": "my-new-bucket"
}
```
**存储桶已存在 (200)**
```json
{
"success": false,
"message": "存储桶已存在: my-new-bucket",
"bucket_name": "my-new-bucket"
}
```
#### cURL 示例
```bash
curl -X POST "http://localhost:8000/api/v2/storage/buckets" \
-H "Content-Type: application/json" \
-d '{"bucket_name": "my-new-bucket"}'
```
---
### 2. 删除存储桶
**DELETE** `/api/v2/storage/buckets`
删除 MinIO 存储桶。支持强制删除(会先删除桶内所有文件)。
#### 请求体
```json
{
"bucket_name": "my-bucket",
"force": true
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| bucket_name | string | 是 | 存储桶名称 |
| force | boolean | 否 | 强制删除(默认 false,为 true 时会先删除桶内所有文件) |
#### 响应示例
**成功 (200)**
```json
{
"success": true,
"message": "存储桶删除成功",
"bucket_name": "my-bucket",
"files_deleted": 15
}
```
**存储桶不存在 (200)**
```json
{
"success": false,
"message": "存储桶不存在: my-bucket",
"bucket_name": "my-bucket",
"files_deleted": 0
}
```
#### cURL 示例
```bash
# 普通删除(桶必须为空)
curl -X DELETE "http://localhost:8000/api/v2/storage/buckets" \
-H "Content-Type: application/json" \
-d '{"bucket_name": "my-bucket"}'
# 强制删除(会删除桶内所有文件)
curl -X DELETE "http://localhost:8000/api/v2/storage/buckets" \
-H "Content-Type: application/json" \
-d '{"bucket_name": "my-bucket", "force": true}'
```
---
### 3. 列出存储桶
**GET** `/api/v2/storage/buckets`
列出所有 MinIO 存储桶。
#### 响应示例
```json
{
"success": true,
"message": "共 3 个存储桶",
"buckets": [
{
"name": "docauditai",
"creation_date": "2024-01-15T08:30:00+00:00"
},
{
"name": "backup",
"creation_date": "2024-02-20T10:15:00+00:00"
},
{
"name": "temp",
"creation_date": "2024-03-01T14:00:00+00:00"
}
]
}
```
#### cURL 示例
```bash
curl -X GET "http://localhost:8000/api/v2/storage/buckets"
```
---
## 文件操作
### 4. 复制文件
**POST** `/api/v2/storage/files/copy`
在 MinIO 内复制文件。支持跨存储桶复制。
#### 请求体
```json
{
"source_path": "documents/contract.pdf",
"destination_path": "backup/contract-2024.pdf",
"source_bucket": null,
"destination_bucket": null
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| source_path | string | 是 | 源文件路径 |
| destination_path | string | 是 | 目标文件路径 |
| source_bucket | string | 否 | 源存储桶(默认使用配置的默认桶) |
| destination_bucket | string | 否 | 目标存储桶(默认使用配置的默认桶) |
#### 响应示例
```json
{
"success": true,
"message": "文件复制成功",
"source_path": "docauditai/documents/contract.pdf",
"destination_path": "docauditai/backup/contract-2024.pdf"
}
```
#### cURL 示例
```bash
# 同桶内复制
curl -X POST "http://localhost:8000/api/v2/storage/files/copy" \
-H "Content-Type: application/json" \
-d '{
"source_path": "documents/contract.pdf",
"destination_path": "backup/contract-2024.pdf"
}'
# 跨桶复制
curl -X POST "http://localhost:8000/api/v2/storage/files/copy" \
-H "Content-Type: application/json" \
-d '{
"source_path": "documents/contract.pdf",
"destination_path": "contract.pdf",
"source_bucket": "docauditai",
"destination_bucket": "backup"
}'
```
---
### 5. 移动/重命名文件
**POST** `/api/v2/storage/files/move`
移动文件(复制后删除源文件)。在同一目录内移动即为重命名。
#### 请求体
```json
{
"source_path": "documents/old-name.pdf",
"destination_path": "documents/new-name.pdf"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| source_path | string | 是 | 源文件路径 |
| destination_path | string | 是 | 目标文件路径 |
#### 响应示例
```json
{
"success": true,
"message": "文件移动成功",
"source_path": "documents/old-name.pdf",
"destination_path": "documents/new-name.pdf"
}
```
#### cURL 示例
```bash
# 重命名文件
curl -X POST "http://localhost:8000/api/v2/storage/files/move" \
-H "Content-Type: application/json" \
-d '{
"source_path": "documents/report-v1.pdf",
"destination_path": "documents/report-v2.pdf"
}'
# 移动到其他目录
curl -X POST "http://localhost:8000/api/v2/storage/files/move" \
-H "Content-Type: application/json" \
-d '{
"source_path": "temp/upload.pdf",
"destination_path": "documents/final.pdf"
}'
```
---
### 6. 删除单个文件
**DELETE** `/api/v2/storage/files`
删除 MinIO 中的单个文件。
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| file_path | string | 是 | 文件路径 |
#### 响应示例
**成功 (200)**
```json
{
"success": true,
"message": "文件删除成功",
"file_path": "documents/old-file.pdf"
}
```
**文件不存在 (200)**
```json
{
"success": false,
"message": "文件不存在: documents/old-file.pdf",
"file_path": "documents/old-file.pdf"
}
```
#### cURL 示例
```bash
curl -X DELETE "http://localhost:8000/api/v2/storage/files?file_path=documents/old-file.pdf"
```
---
### 7. 批量删除文件
**POST** `/api/v2/storage/files/batch-delete`
批量删除多个文件。
#### 请求体
```json
{
"file_paths": [
"temp/file1.pdf",
"temp/file2.pdf",
"temp/file3.pdf"
]
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| file_paths | string[] | 是 | 文件路径列表(至少1个) |
#### 响应示例
```json
{
"success": true,
"message": "删除完成: 成功 3, 失败 0",
"deleted_count": 3,
"failed_count": 0,
"failed_paths": []
}
```
**部分失败 (200)**
```json
{
"success": false,
"message": "删除完成: 成功 2, 失败 1",
"deleted_count": 2,
"failed_count": 1,
"failed_paths": ["temp/not-exist.pdf"]
}
```
#### cURL 示例
```bash
curl -X POST "http://localhost:8000/api/v2/storage/files/batch-delete" \
-H "Content-Type: application/json" \
-d '{
"file_paths": [
"temp/file1.pdf",
"temp/file2.pdf",
"temp/file3.pdf"
]
}'
```
---
### 8. 下载文件
**GET** `/api/v2/storage/files/download`
从 MinIO 下载文件。返回文件流。
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| file_path | string | 是 | 文件路径 |
| filename | string | 否 | 下载时显示的文件名 |
#### 响应
返回文件二进制流,包含以下响应头:
```
Content-Type: application/pdf
Content-Disposition: attachment; filename="contract.pdf"
Content-Length: 1234567
```
#### cURL 示例
```bash
# 下载文件
curl -X GET "http://localhost:8000/api/v2/storage/files/download?file_path=documents/contract.pdf" \
-o contract.pdf
# 指定下载文件名
curl -X GET "http://localhost:8000/api/v2/storage/files/download?file_path=documents/contract.pdf&filename=my-contract.pdf" \
-o my-contract.pdf
```
#### 浏览器直接下载
```
http://localhost:8000/api/v2/storage/files/download?file_path=documents/contract.pdf
```
---
### 9. 列出目录文件
**GET** `/api/v2/storage/files`
列出指定目录下的文件。
#### 请求参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| directory_path | string | 否 | "" | 目录路径 |
| recursive | boolean | 否 | false | 是否递归列出子目录 |
| max_files | int | 否 | 100 | 最大返回数量(1-1000) |
| marker | string | 否 | null | 分页标记 |
#### 响应示例
```json
{
"success": true,
"message": "共 5 个文件",
"files": [
"documents/contract-001.pdf",
"documents/contract-002.pdf",
"documents/contract-003.pdf",
"documents/report.docx",
"documents/summary.xlsx"
],
"total_count": 5,
"next_marker": null
}
```
**分页响应 (200)**
```json
{
"success": true,
"message": "共 100 个文件",
"files": ["..."],
"total_count": 100,
"next_marker": "documents/file-100.pdf"
}
```
#### cURL 示例
```bash
# 列出根目录
curl -X GET "http://localhost:8000/api/v2/storage/files"
# 列出指定目录
curl -X GET "http://localhost:8000/api/v2/storage/files?directory_path=documents"
# 递归列出
curl -X GET "http://localhost:8000/api/v2/storage/files?directory_path=documents&recursive=true"
# 分页查询
curl -X GET "http://localhost:8000/api/v2/storage/files?directory_path=documents&max_files=50"
# 获取下一页
curl -X GET "http://localhost:8000/api/v2/storage/files?directory_path=documents&max_files=50&marker=documents/file-50.pdf"
```
---
### 10. 获取文件元数据
**GET** `/api/v2/storage/files/metadata`
获取文件的详细元数据信息。
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| file_path | string | 是 | 文件路径 |
#### 响应示例
```json
{
"success": true,
"message": "获取成功",
"file_info": {
"path": "documents/contract.pdf",
"size": 1234567,
"content_type": "application/pdf",
"created_time": "2024-03-15T10:30:00+00:00",
"modified_time": "2024-03-15T10:30:00+00:00",
"etag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"url": "http://minio:9000/docauditai/documents/contract.pdf?X-Amz-..."
}
}
```
#### cURL 示例
```bash
curl -X GET "http://localhost:8000/api/v2/storage/files/metadata?file_path=documents/contract.pdf"
```
---
### 11. 获取预签名URL
**GET** `/api/v2/storage/files/presigned-url`
获取文件的预签名下载URL,可用于临时分享。
#### 请求参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| file_path | string | 是 | - | 文件路径 |
| expires | int | 否 | 3600 | 过期时间(秒),范围 60-604800(7天) |
#### 响应示例
```json
{
"success": true,
"message": "获取成功",
"url": "http://minio:9000/docauditai/documents/contract.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
"expires_in": 3600
}
```
#### cURL 示例
```bash
# 默认1小时过期
curl -X GET "http://localhost:8000/api/v2/storage/files/presigned-url?file_path=documents/contract.pdf"
# 自定义过期时间(1天)
curl -X GET "http://localhost:8000/api/v2/storage/files/presigned-url?file_path=documents/contract.pdf&expires=86400"
# 最长7天
curl -X GET "http://localhost:8000/api/v2/storage/files/presigned-url?file_path=documents/contract.pdf&expires=604800"
```
---
## 前端集成示例
### JavaScript/Fetch
```javascript
const API_BASE = 'http://localhost:8000/api/v2/storage';
// 列出存储桶
async function listBuckets() {
const response = await fetch(`${API_BASE}/buckets`);
return response.json();
}
// 创建存储桶
async function createBucket(bucketName) {
const response = await fetch(`${API_BASE}/buckets`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ bucket_name: bucketName })
});
return response.json();
}
// 复制文件
async function copyFile(sourcePath, destPath) {
const response = await fetch(`${API_BASE}/files/copy`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
source_path: sourcePath,
destination_path: destPath
})
});
return response.json();
}
// 重命名文件
async function renameFile(oldPath, newPath) {
const response = await fetch(`${API_BASE}/files/move`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
source_path: oldPath,
destination_path: newPath
})
});
return response.json();
}
// 删除文件
async function deleteFile(filePath) {
const response = await fetch(
`${API_BASE}/files?file_path=${encodeURIComponent(filePath)}`,
{ method: 'DELETE' }
);
return response.json();
}
// 下载文件
function downloadFile(filePath, filename) {
const url = `${API_BASE}/files/download?file_path=${encodeURIComponent(filePath)}`;
if (filename) {
url += `&filename=${encodeURIComponent(filename)}`;
}
window.open(url, '_blank');
}
// 获取文件列表
async function listFiles(directory = '', recursive = false) {
const params = new URLSearchParams({
directory_path: directory,
recursive: recursive.toString()
});
const response = await fetch(`${API_BASE}/files?${params}`);
return response.json();
}
// 获取预签名URL
async function getPresignedUrl(filePath, expires = 3600) {
const params = new URLSearchParams({
file_path: filePath,
expires: expires.toString()
});
const response = await fetch(`${API_BASE}/files/presigned-url?${params}`);
return response.json();
}
```
### Vue 3 组件示例
```vue
```
---
## 错误处理
所有接口返回统一格式:
```json
{
"success": false,
"message": "错误描述信息"
}
```
### 常见错误
| 错误 | 说明 | 解决方案 |
|------|------|----------|
| 存储桶不存在 | 操作的存储桶未找到 | 检查桶名是否正确 |
| 文件不存在 | 操作的文件路径无效 | 检查文件路径 |
| 存储桶非空 | 删除桶时桶内有文件 | 使用 force=true 强制删除 |
| 权限不足 | MinIO 访问凭证问题 | 检查配置的 access_key/secret_key |
---
## 测试
使用测试脚本进行完整测试:
```bash
python scripts/test_minio_api.py --host localhost --port 8000
```