JCS-pub/docs/JCS_pub_API_en.md

35 KiB
Raw Permalink Blame History

JCS-pub API

Back to README.md

1 Bucket Operations

1.1 Create Bucket

Request
POST application/json /v1/bucket/create
Query None
Body
{
    "userID": 1,
    "name": "bkt1"  // Bucket name
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "bucket": {
            "bucketID": 1,   // Bucket ID
            "name": "bkt1"   // Bucket name
        }
    }
}

1.2 Get Bucket by Name

Request
GET application/json /v1/bucket/getByName
Query

- namestring // Bucket name

Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
      "bucket": {
        "bucketID": 1,  // Bucket ID
        "name": "bkt1"  // Bucket name
      }
    }
}

1.3 List Buckets

Request
GET application/json /v1/bucket/listAll
Query None
Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
      "buckets": [{
        "bucketID": 1,  // Bucket ID
        "name": "bkt1"  // Bucket name
      }]
    }
}

1.4 Delete Bucket

Request
POST application/json /v1/bucket/delete
Query None
Body
{
    "bucketID":1
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": null
}

2 Package Operations

2.1 Create Package

Request
POST application/json /v1/package/create
Query None
Body
{
    "bucketID":1,
    "name": ""  // Package name
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "package": {
            "packageID": 32,
            "name": "t1",
            "bucketID": 1,
            "createTime": "2025-06-24T16:31:28.5148754+08:00"
        }
    }
}

2.2 Get Package by Bucket Name and Package Name

Request
GET application/json /v1/package/getByFullName
Query

- bucketNamestring // Bucket name - packageNamestring // Package name

Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "package": {
            "packageID": 32,
            "name": "t1",
            "bucketID": 1,
            "createTime": "2025-06-24T16:31:28.5148754+08:00"
        }
    }
}

2.3 List Packages in Bucket

Request
GET application/json /v1/package/listBucketPackages
Query

- bucketIDint64 // Bucket ID

Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
      "packages":[{
            "packageID": 32,
            "name": "t1",
            "bucketID": 1,
            "createTime": "2025-06-24T16:31:28.5148754+08:00"
        }]
    }
}

2.4 Delete Package

Request
POST application/json /v1/package/delete
Query None
Body
{
    "packageID":1
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": null
}

3 Object Operations

3.1 Batch Upload Objects

Request
POST multipart/form-data; boundary=xxxxxxx /v1/object/upload
Query None
Body

Afterwards, the request body is split into multiple parts using the boundary. The first part must have the name info and follow this JSON format:

{
  "packageID": 1,  // Package ID, obtained from the response of the Create Package API
  "affinity": 1  // Preferred storage space for uploading the file (optional)
}

Each subsequent part is a file. The name should be files, and the filename should be the file path (must be URL-encoded). Example:

POST /object/upload HTTP/1.1
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: c12fa8b5-d902-46f3-b104-028effa0d531
Host: localhost:7890
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=-----------------------------818270992847011232305151
Content-Length: 1649

-----------------------------818270992847011232305151
Content-Disposition: form-data; name="info"

{
	"userID": 1,
	"packageID": 1
}
-----------------------------818270992847011232305151
Content-Disposition: form-data; name="files"; filename="test.txt"
Content-Type: text/plain

testdata
-----------------------------818270992847011232305151
Content-Disposition: form-data; name="files"; filename="a%2Fb%2Ftest2.txt"

testdata2
-----------------------------818270992847011232305151--
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "uploadeds": [
            {
                "objectID": 7,
                "packageID": 1,
                "path": "test.txt",
                "size": "123456",
                "fileHash": "xxxxxxxxxx",
                "redundancy": {
                    "type": "none"
                },
                "createTime": "2024-11-05T11:06:28+08:00",
                "updateTime": "2025-01-10T09:15:39.4452196+08:00"
            },
            {
                "objectID": 8,
                "packageID": 1,
                "path": "a/b/test2.txt",
                "size": "123456",
                "fileHash": "xxxxxxxxxx",
                "redundancy": {
                    "type": "none"
                },
                "createTime": "2024-11-05T11:06:28+08:00",
                "updateTime": "2025-01-10T09:15:39.4452196+08:00"
            }
        ]
    }
}

3.2 Download Object

Request
GET application/json /v1/object/download
Query

- objectIDint64 - offsetint64 - lengthint64 // Length to read. If not provided, the entire object will be read.

Body None
Response Example

If the request is successful, the Content-Type will be application/octet-stream and the response body will contain the file data.
If the request fails, the Content-Type will be application/json and the response body will be in the following format:

{
    "code": "OperationFailed",
    "message": "xxxxxxxx",
    "data": null
}

3.3 Download Object by Path

Request
GET application/json /v1/object/downloadByPath
Query

- pathstring - offsetint64 - lengthint64 // Length to read. If not provided, the entire object will be read.

Body None
Response Example

If the request is successful, the Content-Type will be application/octet-stream and the response body will contain the file data.
If the request fails, the Content-Type will be application/json and the response body will be in the following format:

{
    "code": "OperationFailed",
    "message": "xxxxxxxx",
    "data": null
}

3.4 Get Object by Path

Request
GET application/json /v1/object/listByPath
Query

- packageIDint64 - pathstring - isPrefixbool // If true, perform a prefix search using the path parameter - noRecursivebool // If true, when performing a prefix search, the results will separate objects and "directories" like a directory listing - maxKeysint // Maximum number of results returned in this query (the total number of items in commonPrefixes + objects) - continuationTokenstring // Start this query from the position specified by the token; leave empty to start from the beginning. This value should be the same as the corresponding field from the previous response.

Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "nextContinuationToken": "123456", // Used for the next paginated query
        "isTruncated": false, // If true, it indicates more results are available for the next query
        "commonPrefixes": [
            "a/b/",
            "a/c/"
        ],
        "objects": [
            {
                "objectID": 617,
                "packageID": 12,
                "path": "a/1.txt",
                "size": "1293",
                "fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
                "redundancy": {
                    "type": "none"
                },
                "createTime": "2024-11-19T16:02:25+08:00",
                "updateTime": "2024-11-19T16:02:25+08:00"
            },
            {
                "objectID": 618,
                "packageID": 12,
                "path": "a/2.txt",
                "size": "1293",
                "fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
                "redundancy": {
                    "type": "none"
                },
                "createTime": "2024-11-19T16:02:25+08:00",
                "updateTime": "2024-11-19T16:02:25+08:00"
            }
        ]
    }
}

3.5 List Objects in Package

Request
GET application/json /v1/object/getPackageObjects
Query

- packageIDint64

Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "objects": [
            {
                "objectID": 617,
                "packageID": 12,
                "path": "a/1.txt",
                "size": "1293",
                "fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
                "redundancy": {
                    "type": "none"
                },
                "createTime": "2024-11-19T16:02:25+08:00",
                "updateTime": "2024-11-19T16:02:25+08:00"
            },
            {
                "objectID": 618,
                "packageID": 12,
                "path": "a/2.txt",
                "size": "1293",
                "fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
                "redundancy": {
                    "type": "none"
                },
                "createTime": "2024-11-19T16:02:25+08:00",
                "updateTime": "2024-11-19T16:02:25+08:00"
            }
        ]
    }
}

3.6 Batch Move Objects

Request
POST application/json /v1/object/move
Query None
Body
{
    "movings":[
        {
            "objectID":4, // Original object ID
            "packageID":3, // Target package ID after moving
            "path":"trace2.txt" // Target path after moving
        }
    ]
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
      "successes": [ // IDs of successfully moved objects
        4
      ]
    }
}

3.7 Batch Delete Objects

Request
POST application/json /v1/object/delete
Query None
Body
{
    "objectIDs":[
      4
    ]
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": null
}

The response code will be OK even if the file does not exist.

3.8 Batch Copy Objects

Request
POST application/json /v1/object/clone
Query None
Body
{
    "clonings": [
        {
            "objectID": 4,  // Original object ID
            "newPath": "trace3.txt",  // The new object's path
            "newPackageID": 3  // The new object's package ID
        }
    ]
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
      "objects":[{
                "objectID": 5,
                "packageID": 3,
                "path": "trace3.txt",
                "size": "1293",
                "fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
                "redundancy": {
                    "type": "none"
                },
                "createTime": "2024-11-19T16:02:25+08:00",
                "updateTime": "2024-11-19T16:02:25+08:00"
       }]
    }
}

3.9 Create Multipart Upload

Request
POST application/json /v1/object/newMultipartUpload
Query None
Body
{
    "packageID": 3,
    "path": "multi"  // The object's path
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "object": {
            "objectID": 1039,
            "packageID": 3,
            "path": "obj.txt",
            "size": "0",
            "fileHash": "Full0000000000000000000000000000000000000000000000000000000000000000",
            "redundancy": {
                "type": "multipartUpload"
            },
            "createTime": "2025-03-04T16:03:18+08:00",
            "updateTime": "2025-03-11T15:20:44.5182982+08:00"
        }
    }
}

The created object can be found using the query interface.

3.10 Upload Part

Request
POST multipart/form-data; boundary=xxxxxxx /v1/object/uploadPart
Query None
Body

Similar to the object upload interface, the request must contain two parts: info and file. The info part should have the following format:

{
  "objectID": 1, // The Object ID obtained from the Create Multipart Upload API
  "index": 1 // The part number used for merging later. Parts with the same index will overwrite the old data.
}

The file part contains the file data.

Response Example
{
    "code": "OK",
    "message": ""
}

3.11 Complete Multipart Upload

Request
POST application/json /v1/object/completeMultipartUpload
Query None
Body
{
    "objectID": 1039,  // The Object ID to be merged
    "indexes": [2,3,1]  // The list of part numbers. Duplicate part numbers are allowed; parts will be merged in the specified order. Unused parts will be discarded.
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "object": {
            "objectID": 1039,
            "packageID": 3,
            "path": "obj.txt",
            "size": "30",
            "fileHash": "FullB7660EB37969EDC68202258A1838B89493B4C77EA006B1640768D20CEF7A7CD2",
            "redundancy": {
                "type": "none"
            },
            "createTime": "2025-03-04T16:03:18+08:00",
            "updateTime": "2025-03-11T15:42:03+08:00"
        }
    }
}

4 User Storage Configuration

4.1 Create User Storage Configuration

Request
POST application/json /v1/userSpace/create
Query None
Body
{
    "name": "test1",
    "storage": { // Storage system type
        "type": "OBS",
        "region": "",
        "endpoint": "",
        "bucket": "",
        "projectID": ""
    },
    "credential": { // Permission information required to access the storage system
        "type": "OBS",
        "accessKeyId": "",
        "secretAccessKey": ""
    },
    "shardStore": { // Configuration for shard storage; if null, shard storage is disabled
        "maxSize":1024
    },
    "features": [], // Configuration of feature functions for the storage system
    "workingDir": "" // Root directory for storing data of various components, including shard storage
}

- The content of storage and credential is determined by the value of the type field. You can find more type definitions in the package at gitlink.org.cn/cloudream/jcs-pub/coordinator/types. - Features configures the feature functions of the storage system; the specific available features can also be referenced from the package above. Note: Not all storage systems support all features.

Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "userSpace": {
            "userSpaceID": 1,
            "name": "test1",
            "storage": {
                "type": "OBS",
                "region": "",
                "endpoint": "",
                "bucket": "",
                "projectID": ""
            },
            "credential": {
                "type": "OBS",
                "accessKeyId": "",
                "secretAccessKey": ""
            },
            "shardStore": {
                "maxSize": 1024
            },
            "features": [],
            "workingDir": "",
            "revision": 1
        }
    }
}

4.2 Update User Storage Configuration

Request
POST application/json /v1/userSpace/update
Query None
Body
{
    "userSpaceID": 1,
    "name": "test1",  // New name
    "credential": {   // New credential information
        "type": "OBS",
        "accessKeyId": "",
        "secretAccessKey": ""
    }
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "userSpace": {
            "userSpaceID": 1,
            "name": "test1",
            "storage": {
                "type": "OBS",
                "region": "",
                "endpoint": "",
                "bucket": "",
                "projectID": ""
            },
            "credential": {
                "type": "OBS",
                "accessKeyId": "",
                "secretAccessKey": ""
            },
            "shardStore": {
                "maxSize": 1024
            },
            "features": [],
            "workingDir": "",
            "revision": 1
        }
    }
}

4.3 Delete User Storage Configuration

Request
POST application/json /v1/userSpace/delete
Query None
Body
{
    "userSpaceID": 1
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": null
}

The response code will be OK even if the file does not exist.

4.4 Get User Storage Configuration

Request
GET application/json /v1/userSpace/get
Query

- userSpaceID: int64

Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "userSpace": {
            "userSpaceID": 1,
            "name": "test1",
            "storage": {
                "type": "OBS",
                "region": "",
                "endpoint": "",
                "bucket": "",
                "projectID": ""
            },
            "credential": {
                "type": "OBS",
                "accessKeyId": "",
                "secretAccessKey": ""
            },
            "shardStore": {
                "maxSize": 1024
            },
            "features": [],
            "workingDir": "",
            "revision": 1
        }
    }
}

4.5 Test User Storage Configuration

Request
POST application/json /v1/userSpace/test
Query None
Body
{
    "storage": {
        "type": "OBS",
        "region": "",
        "endpoint": "",
        "bucket": "",
        "projectID": ""
    },
    "credential": {
        "type": "OBS",
        "accessKeyId": "",
        "secretAccessKey": ""
    },
    "workingDir": ""
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": null
}

The OK response indicates the configuration is valid and connected to the storage system.

4.6 Upload to New Package from User Storage

Request
POST application/json /v1/userSpace/createPackage
Query None
Body
{
    "userSpaceID": 1,
    "path": "",  // Path within the user's storage space. Can be a folder or a file. Note: WorkingDir is not prepended.
    "bucketID": 1,  // bucketID of the newly created package
    "name": "",  // Name of the newly created package
    "spaceAffinity": 0  // Preferred storage space for uploading files. 0 means no preference.
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "package": {
            "packageID": 32,
            "name": "t1",
            "bucketID": 1,
            "createTime": "2025-06-24T16:31:28.5148754+08:00"
        }
    }
}

4.7 Download Package to User Storage

Request
POST application/json /v1/userSpace/downloadPackage
Query None
Body
{
    "userSpaceID": 1,
    "packageID": 1,
    "rootPath": "", // Root path for storing downloaded files
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": null
}

5 User Storage Sync

5.1 Create Sync Task

Request
POST application/json /v1/spaceSyncer/createTask
Query None
Body
{
    "trigger": { // Sync task trigger condition
        "type": "Interval",
        "interval": 30
    },
    "mode": { // Sync mode
        "type": "Diff",
        "includeSize": false,
        "includeModTime": true
    },
    "filters": [ // Filter rules
        {
            "type": "Size",
            "minSize": 10,
            "maxSize": 20000
        }
    ],
    "options": { // Options
        "noEmptyDirectories": false
    }, 
    "srcUserSpaceID": 1, // Source storage space ID
    "srcPath": "space1/cli", // Path within source storage space
    "destUserSpaceIDs": [ // Destination storage space IDs
        2
    ],
    "destPathes": [ // Paths within destination storage spaces
        "space2/svr"
    ]
}

The contents of trigger, mode, and filters vary according to their type fields. For more details, please refer to the package at gitlink.org.cn/cloudream/jcs-pub/client/types.

Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "task": {
            "taskID": 1,
            "trigger": {
                "type": "Interval",
                "interval": 30
            },
            "mode": {
                "type": "Diff",
                "includeSize": false,
                "includeModTime": true
            },
            "filters": [
                {
                    "type": "Size",
                    "minSize": 10,
                    "maxSize": 20000
                }
            ],
            "options": {
                "noEmptyDirectories": false
            },
            "srcUserSpaceID": 1,
            "srcPath": "space1/cli",
            "destUserSpaceIDs": [
                2
            ],
            "destPathes": [
                "space2/svr"
            ]
        }
    }
}

5.2 Get Sync Task

Request
GET application/json /v1/spaceSyncer/getTask
Query

- taskID: int64

Body None
Response Example
{
    "code": "OK",
    "message": "",
    "data": {
        "task": {
            "taskID": 1,
            "trigger": {
                "type": "Interval",
                "interval": 30
            },
            "mode": {
                "type": "Diff",
                "includeSize": false,
                "includeModTime": true
            },
            "filters": [
                {
                    "type": "Size",
                    "minSize": 10,
                    "maxSize": 20000
                }
            ],
            "options": {
                "noEmptyDirectories": false
            },
            "srcUserSpaceID": 1,
            "srcPath": "space1/cli",
            "destUserSpaceIDs": [
                2
            ],
            "destPathes": [
                "space2/svr"
            ]
        }
    }
}

5.3 Cancel Sync Task

Request
POST application/json /v1/spaceSyncer/cancelTask
Query None
Body
{
    "taskID": 1
}
Response Example
{
    "code": "OK",
    "message": "",
    "data": null
}