Files
Oxicloud/doc/batch-operations.md
T
2026-04-01 23:14:42 +02:00

3.9 KiB

09 - Batch Operations

Batch endpoints let you perform bulk file and folder operations (move, copy, delete, get, create) in a single request. Operations run concurrently behind a configurable semaphore. Each response includes detailed per-item success/failure info.

Architecture

Layer Component File
Application Service BatchOperationService src/application/services/batch_operations.rs
Interfaces batch_handler functions src/interfaces/api/handlers/batch_handler.rs

REST API

All routes live under /api/batch and require authentication.

File Operations

Method Path Handler Description
POST /api/batch/files/move move_files_batch Move files to target folder
POST /api/batch/files/copy copy_files_batch Copy files to target folder
POST /api/batch/files/delete delete_files_batch Delete multiple files
POST /api/batch/files/get get_files_batch Get metadata for multiple files

Folder Operations

Method Path Handler Description
POST /api/batch/folders/delete delete_folders_batch Delete multiple folders
POST /api/batch/folders/create create_folders_batch Create multiple folders
POST /api/batch/folders/get get_folders_batch Get metadata for multiple folders

Request DTOs

File Operations

{
  "file_ids": ["id-1", "id-2", "id-3"],
  "target_folder_id": "folder-abc"      // required for move/copy
}

Folder Delete

{
  "folder_ids": ["folder-1", "folder-2"],
  "recursive": true,
  "target_folder_id": null
}

Folder Create

{
  "folders": [
    { "name": "Documents", "parent_id": null },
    { "name": "Photos", "parent_id": "folder-abc" }
  ]
}

Response Format

Every batch endpoint returns the same structure:

{
  "successful": [ ... ],
  "failed": [
    { "id": "bad-id", "error": "File not found" }
  ],
  "stats": {
    "total": 5,
    "successful": 4,
    "failed": 1,
    "execution_time_ms": 245
  }
}

Status Codes

Code Meaning
200 OK / 201 Created All operations succeeded
206 Partial Content Some succeeded, some failed
400 Bad Request All operations failed

Concurrency

Operations run concurrently via tokio::sync::Semaphore, capped by max_concurrent_files (default: 10).

pub struct BatchOperationService {
    file_retrieval: Arc<dyn FileRetrievalUseCase>,
    file_management: Arc<dyn FileManagementUseCase>,
    folder_service: Arc<FolderService>,
    config: AppConfig,
    semaphore: Arc<Semaphore>,
}

Error Handling

pub enum BatchOperationError {
    Domain(DomainError),                    // individual operation error
    Cancelled(String),                      // operation was cancelled
    ConcurrencyLimit(String),               // semaphore exhausted
    PartialFailure(String, usize, usize),   // message, success_count, fail_count
    Internal(String),
}

Individual failures do not abort the batch. They get collected in the failed array and the response returns 206 Partial Content.

Example

# Move 3 files to a folder
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"file_ids":["id-1","id-2","id-3"],"target_folder_id":"folder-abc"}' \
  "https://oxicloud.example.com/api/batch/files/move"

# Delete folders recursively
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"folder_ids":["old-1","old-2"],"recursive":true}' \
  "https://oxicloud.example.com/api/batch/folders/delete"

# Create multiple folders
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"folders":[{"name":"Docs","parent_id":null},{"name":"Photos","parent_id":"root-id"}]}' \
  "https://oxicloud.example.com/api/batch/folders/create"