Skip to content

Thư mục

Thư mục giúp tổ chức các tệp đã tải lên của bạn trên bảng điều khiển. Chúng chỉ là siêu dữ liệu theo mặc định — các tệp giữ nguyên CID riêng và không bị di chuyển trên IPFS — nhưng bạn cũng có thể chụp nhanh một thư mục để hiện thực hóa nó thành một thư mục UnixFS thật và có một CID cho toàn bộ nội dung.

Khi nào bạn nên chụp nhanh một thư mục

Một bản chụp nhanh thư mục là một CID thư mục IPFS duy nhất chứa mọi tệp trong thư mục, có thể định địa chỉ theo tên. Với nó, bạn có thể:

  • Chia sẻ toàn bộ thư mục qua một URL: https://ipfs.ninja/ipfs/{dirCid}/
  • Phân giải trực tiếp https://ipfs.ninja/ipfs/{dirCid}/photo.jpg (hoặc bất kỳ gateway nào khác)
  • Đặt CID vào một ENS contenthash để lưu trữ một trang web tĩnh
  • Dùng nó làm CID gốc của một bộ sưu tập NFT để mỗi token tham chiếu ipfs://{dirCid}/<id>.json
  • Ghim thư mục ở bất kỳ đâu khác — mọi gateway IPFS trên thế giới đều biết cách phân giải một CID thư mục UnixFS

Bản chụp nhanh được định địa chỉ theo nội dung: nội dung thư mục giống hệt nhau luôn tạo ra cùng một CID. Chụp nhanh lại một thư mục bạn chưa thay đổi sẽ trả về cùng CID đã trả về trước đó. Thêm/xóa/đổi tên một tệp sẽ tạo ra một CID mới; CID trước đó vẫn được ghim và có thể phân giải miễn là bạn không xóa các tệp của nó.

Tạo thư mục

POST /folders

Tham sốKiểuBắt buộcMô tả
namestringTên hiển thị.
parentFolderIdstring | nullKhôngID thư mục cha cho thư mục lồng nhau. Bỏ qua để tạo thư mục gốc.

Ví dụ

bash
curl -X POST https://api.ipfs.ninja/folders \
  -H "X-Api-Key: bws_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "name": "My NFT collection" }'

Trả về:

json
{
  "folderId": "1f8e2c3a-…",
  "name": "My NFT collection",
  "parentFolderId": null,
  "createdAt": 1746360000000
}

Các thư mục mới tạo không có bản chụp nhanh. Trường latestSnapshot xuất hiện trên thư mục ngay khi bạn gọi POST /folders/{id}/snapshot (xem bên dưới) và trong các phản hồi GET /folders tiếp theo.

Liệt kê thư mục

GET /folders

Trả về mọi thư mục trong tài khoản của bạn, cả cấp gốc lẫn lồng nhau, cùng với CID chụp nhanh gần nhất cho mỗi thư mục (nếu có).

json
[
  {
    "folderId": "1f8e2c3a-…",
    "name": "My NFT collection",
    "parentFolderId": null,
    "createdAt": 1746360000000,
    "fileCount": 42,
    "latestSnapshot": {
      "cid": "QmRZx5…",
      "takenAt": 1746421000000,
      "fileCount": 42
    }
  }
]

fileCount phản ánh nội dung hiện tại của thư mục; latestSnapshot.fileCount phản ánh nội dung tại thời điểm chụp nhanh gần nhất. Nếu chúng khác nhau, CID chụp nhanh vẫn phân giải được nhưng đã cũ — hãy chụp nhanh lại để làm mới.

Di chuyển một tệp vào thư mục

PUT /files/{cid}/move

Tham sốKiểuBắt buộcMô tả
folderIdstring | nullID thư mục đích, hoặc null để di chuyển tệp về thư mục gốc.
bash
curl -X PUT https://api.ipfs.ninja/files/Qm.../move \
  -H "X-Api-Key: bws_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "folderId": "1f8e2c3a-…" }'

Chụp nhanh một thư mục (lấy CID thư mục UnixFS)

POST /folders/{folderId}/snapshot

Hiện thực hóa thư mục thành một thư mục UnixFS thật trên cụm IPFS và ghim kết quả. Trả về một CID cho toàn bộ thư mục. Tên của các tệp con lấy từ fileName của mỗi tệp; các tên trùng lặp được tự động loại bỏ xung đột.

Không cần nội dung yêu cầu; tham số đường dẫn xác định thư mục.

Ví dụ

bash
curl -X POST https://api.ipfs.ninja/folders/1f8e2c3a-.../snapshot \
  -H "X-Api-Key: bws_your_api_key_here"

Trả về:

json
{
  "ok": true,
  "folderId": "1f8e2c3a-…",
  "cid": "QmRZx5VgFHDsG7ECvaKkZBS4ydmkdAkDyaKyF71RYvh8",
  "fileCount": 42,
  "sizeBytes": 8421376,
  "takenAt": 1746421000000,
  "ipfsUrl": "https://ipfs.ninja/ipfs/QmRZx5.../"
}

CID cũng được lưu trên hàng thư mục, nên các lệnh GET /folders tiếp theo sẽ trả về nó dưới dạng latestSnapshot.cid mà không cần chụp nhanh lại.

Phân giải một bản chụp nhanh

Ngay khi một bản chụp nhanh được ghim, CID thư mục phân giải qua bất kỳ gateway IPFS nào. Mẫu URL đơn giản nhất:

https://ipfs.ninja/ipfs/{dirCid}/         → danh sách thư mục
https://ipfs.ninja/ipfs/{dirCid}/photo.jpg → tệp đó

Cụm ghim theo kiểu đệ quy, nên các tệp con cũng có thể phân giải được — ngay cả khi sau đó bạn xóa tệp gốc khỏi tài khoản của mình, bản sao trong bản chụp nhanh vẫn tồn tại vì đó là một pin riêng biệt đệ quy qua thư mục.

Chụp nhanh lại

Chụp nhanh lại một thư mục không thay đổi sẽ trả về cùng CID — CID thư mục được định địa chỉ theo nội dung, nên nội dung giống hệt nhau luôn tạo ra cùng một hàm băm, và lệnh ghim của cụm nhận ra bản trùng lặp và không thực hiện gì thêm.

Lưu ý: bản thân đường dẫn chụp nhanh không miễn phí ngay cả khi kết quả là cùng một CID. Mỗi lệnh gọi đọc lại byte của mọi tệp từ IPFS và tải lại chúng dưới dạng multipart vào endpoint /add của cụm — đó là nơi diễn ra việc bọc-trong-thư-mục. Đối với các thư mục thông thường (≤100 tệp nhỏ), việc này vẫn hoàn tất trong vài giây; với các thư mục rất lớn, hãy ưu tiên chỉ gọi chụp nhanh khi nội dung thực sự thay đổi.

Gọi chụp nhanh sau khi bạn đã thêm hoặc xóa tệp sẽ tạo ra một CID khác; CID trước đó vẫn tiếp tục phân giải miễn là bạn không xóa các tệp gốc của nó.

Giới hạn

  • Thư mục phải chứa ít nhất một tệp. Thư mục rỗng trả về 400 — folder is empty.
  • Các ký tự trong tên tệp được mã hóa URL trong bản tải lên multipart mà Kubo chấp nhận; URL gateway có thể cần mã hóa phần trăm cho khoảng trắng hoặc ký tự không phải ASCII trong tên tệp của bạn.
  • Bản chụp nhanh chỉ tính vào tổng số pin của gói bạn đúng một lần cho mỗi CID duy nhất — các khối tệp được loại bỏ trùng lặp, nên bản chụp nhanh chủ yếu chỉ thêm một node thư mục nhỏ lên trên các tệp bạn đã ghim sẵn.

Cập nhật một thư mục

PUT /folders/{folderId}

Tham sốKiểuBắt buộcMô tả
namestringKhôngTên hiển thị mới.
parentFolderIdstring | nullKhôngĐổi thư mục cha. null di chuyển thư mục về gốc.

Xóa một thư mục

DELETE /folders/{folderId}

Xóa thư mục và lan truyền đệ quy qua mọi tệp và thư mục con bên trong. Áp dụng cùng cơ chế bảo vệ an toàn CID dùng chung như khi xóa từng tệp riêng lẻ — nếu người dùng khác vẫn đang ghim một CID bạn đã tải lên, việc bỏ ghim của bạn không làm mất nó với họ.

json
{
  "deleted": true,
  "filesDeleted": 42,
  "foldersDeleted": 3
}

Cấu hình S3 CORS cho một thư mục / bucket

Các thư mục được lộ ra qua API tương thích S3 đóng vai trò là bucket. Nếu bạn điều khiển API đó từ JavaScript trình duyệt, bạn cần các quy tắc CORS trên bucket để preflight của trình duyệt vượt qua. Hai bề mặt tương đương lưu vào cùng một kho:

  • PUT /folders/{folderId}/cors — endpoint REST này, xác thực bằng JWT (được bảng điều khiển sử dụng)
  • Subresource S3 PUT /{bucket}?cors — xác thực bằng SigV4 (được các AWS SDK sử dụng, xem s3-compatibility.md)

PUT trên endpoint này cũng giữ tên thư mục làm tên bucket duy nhất toàn cục nếu nó chưa được giữ.

PUT /folders/{folderId}/cors

Đặt quy tắc CORS cho bucket S3 của thư mục. Tối đa 5 quy tắc mỗi bucket, tổng 64 KB.

Tham sốKiểuBắt buộcMô tả
rulesCorsRule[]Mảng các quy tắc CORS theo dạng AWS (xem bên dưới). Không được rỗng.
bucketNamestringKhôngTên bucket S3 rõ ràng. Mặc định là tên hiển thị của thư mục. Nếu tên mong muốn đã bị chiếm trên toàn cục, hãy truyền một tên khác ở đây.

Mỗi CorsRule:

TrườngKiểuBắt buộcMô tả
AllowedOriginsstring[]Các nguồn gốc được phép gửi yêu cầu. Hỗ trợ ký tự đại diện (https://*.myapp.com). Dùng * cho bất kỳ nguồn gốc nào.
AllowedMethodsstring[]Một hoặc nhiều trong số GET, HEAD, PUT, POST, DELETE.
AllowedHeadersstring[]KhôngCác tiêu đề trình duyệt có thể gồm trong yêu cầu. Mặc định: không có. Dùng ["*"] để cho phép tất cả (khuyến nghị cho AWS SDK v3, vốn gửi Authorization, x-amz-*, v.v.).
ExposeHeadersstring[]KhôngCác tiêu đề phản hồi có thể đọc được bởi JavaScript trình duyệt. Bao gồm ETagx-amz-meta-cid nếu ứng dụng của bạn cần CID được trả về.
MaxAgeSecondsnumberKhôngThời gian trình duyệt lưu bộ nhớ đệm preflight. 0-86400. Mặc định 3600.
IDstringKhôngNhãn văn bản tự do cho quy tắc.

Ví dụ yêu cầu

bash
curl -X PUT https://api.ipfs.ninja/folders/17f6dfd8-519c-4d0e-8f3a-5988a1d34ef2/cors \
  -H "Authorization: Bearer $COGNITO_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [{
      "AllowedOrigins": ["https://myapp.com", "http://localhost:3000"],
      "AllowedMethods": ["GET", "HEAD", "PUT", "POST", "DELETE"],
      "AllowedHeaders": ["*"],
      "ExposeHeaders": ["ETag", "x-amz-meta-cid", "x-amz-request-id"],
      "MaxAgeSeconds": 3600
    }]
  }'

Phản hồi 200 OK

json
{ "success": true, "rules": [ { "AllowedOrigins": ["https://myapp.com", "http://localhost:3000"], "AllowedMethods": ["GET", "HEAD", "PUT", "POST", "DELETE"], "AllowedHeaders": ["*"], "ExposeHeaders": ["ETag", "x-amz-meta-cid", "x-amz-request-id"], "MaxAgeSeconds": 3600 } ] }

GET /folders/{folderId}/cors

Trả về các quy tắc CORS hiện tại cùng tên bucket (nếu đã được giữ).

json
{
  "rules": [  ],
  "bucketName": "my-project"
}

DELETE /folders/{folderId}/cors

Xóa tất cả quy tắc CORS. Preflight của trình duyệt đến bucket sẽ thất bại theo mặc định cho đến khi các quy tắc mới được đặt.

Lựa chọn thay thế trên bảng điều khiển

Trên trang Tệp, menu hành động của mỗi thư mục có mục S3 CORS mở ra một trình chỉnh sửa dạng biểu mẫu. Cùng kho lưu trữ bên dưới như endpoint REST này và như PutBucketCors qua API S3.