Skip to content

โฟลเดอร์

โฟลเดอร์ช่วยจัดระเบียบไฟล์ที่คุณอัปโหลดในแดชบอร์ด โดยค่าเริ่มต้นเป็นเพียง metadata เท่านั้น — ไฟล์ยังคงมี CID ของตัวเองและไม่ถูกย้ายบน IPFS — แต่คุณยังสามารถ สแนปช็อตโฟลเดอร์ เพื่อทำให้มันเป็นไดเรกทอรี UnixFS จริงและได้ CID เดียวสำหรับทั้งหมด

เมื่อไรควรสแนปช็อตโฟลเดอร์

สแนปช็อตโฟลเดอร์คือ directory CID ของ IPFS เดียวที่มีทุกไฟล์ในโฟลเดอร์ อ้างอิงได้ด้วยชื่อ ด้วยสิ่งนี้คุณสามารถ:

  • แชร์ทั้งโฟลเดอร์ผ่าน URL เดียว: https://ipfs.ninja/ipfs/{dirCid}/
  • แก้ไข https://ipfs.ninja/ipfs/{dirCid}/photo.jpg (หรือ gateway อื่นใด) ได้โดยตรง
  • ใส่ CID ลงใน ENS contenthash เพื่อโฮสต์เว็บไซต์แบบสแตติก
  • ใช้เป็น base CID ของคอลเลกชัน NFT เพื่อให้แต่ละโทเค็นอ้างอิง ipfs://{dirCid}/<id>.json
  • ปักหมุดไดเรกทอรีที่อื่นได้ — ทุก IPFS gateway ในโลกรู้วิธีแก้ไข UnixFS dir CID

สแนปช็อตเป็นแบบcontent-addressed: เนื้อหาโฟลเดอร์ที่เหมือนกันจะให้ CID เดียวกันเสมอ การสแนปช็อตซ้ำของโฟลเดอร์ที่คุณไม่ได้เปลี่ยนแปลงจะส่งคืน CID เดิมที่เคยส่งคืนมาก่อน การเพิ่ม/ลบ/เปลี่ยนชื่อไฟล์จะสร้าง CID ใหม่ CID เดิมจะยังคงปักหมุดและแก้ไขได้ตราบใดที่คุณไม่ลบไฟล์ของมัน

สร้างโฟลเดอร์

POST /folders

พารามิเตอร์ประเภทจำเป็นคำอธิบาย
namestringใช่ชื่อที่แสดง
parentFolderIdstring | nullไม่ID โฟลเดอร์แม่สำหรับโฟลเดอร์ซ้อน ละไว้สำหรับโฟลเดอร์ระดับราก

ตัวอย่าง

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" }'

ส่งคืน:

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

โฟลเดอร์ที่สร้างใหม่จะยังไม่มีสแนปช็อต ฟิลด์ latestSnapshot จะปรากฏบนโฟลเดอร์เมื่อคุณเรียก POST /folders/{id}/snapshot (ดูด้านล่าง) และในการตอบกลับ GET /folders ครั้งถัดไป

แสดงรายการโฟลเดอร์

GET /folders

ส่งคืนทุกโฟลเดอร์ในบัญชีของคุณ ทั้งระดับรากและซ้อน พร้อม CID ของสแนปช็อตล่าสุดของแต่ละอัน (ถ้ามี)

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

fileCount สะท้อนเนื้อหาปัจจุบันของโฟลเดอร์; latestSnapshot.fileCount สะท้อนเนื้อหา ณ เวลาที่สแนปช็อตล่าสุด หากค่าทั้งสองต่างกัน CID ของสแนปช็อตยังคงแก้ไขได้แต่ล้าสมัย — สแนปช็อตใหม่เพื่อรีเฟรช

ย้ายไฟล์เข้าโฟลเดอร์

PUT /files/{cid}/move

พารามิเตอร์ประเภทจำเป็นคำอธิบาย
folderIdstring | nullใช่ID โฟลเดอร์เป้าหมาย หรือ null เพื่อย้ายไฟล์ไปที่ราก
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-…" }'

สแนปช็อตโฟลเดอร์ (รับ UnixFS dir CID)

POST /folders/{folderId}/snapshot

ทำให้โฟลเดอร์เป็นไดเรกทอรี UnixFS จริงบนคลัสเตอร์ IPFS และปักหมุดผลลัพธ์ ส่งคืน CID เดียวสำหรับทั้งโฟลเดอร์ ชื่อของไฟล์ย่อยมาจาก fileName ของแต่ละไฟล์ ชื่อซ้ำจะถูกแก้ไขให้ไม่ชนกันโดยอัตโนมัติ

ไม่จำเป็นต้องมี request body; พารามิเตอร์ path จะระบุโฟลเดอร์

ตัวอย่าง

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

ส่งคืน:

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

CID จะถูกเก็บไว้ในแถวของโฟลเดอร์ด้วย ดังนั้นการเรียก GET /folders ครั้งถัดไปจะส่งคืนเป็น latestSnapshot.cid โดยไม่ต้องสแนปช็อตอีกครั้ง

การแก้ไขสแนปช็อต

เมื่อสแนปช็อตถูกปักหมุดแล้ว directory CID จะแก้ไขได้ผ่าน IPFS gateway ใดก็ได้ รูปแบบ URL ที่ง่ายที่สุด:

https://ipfs.ninja/ipfs/{dirCid}/         → directory listing
https://ipfs.ninja/ipfs/{dirCid}/photo.jpg → that one file

คลัสเตอร์ปักหมุดแบบเรียกซ้ำ ดังนั้นไฟล์ย่อยจึงแก้ไขได้เช่นกัน — แม้ว่าคุณจะลบไฟล์ต้นฉบับออกจากบัญชีของคุณในภายหลัง สำเนาของสแนปช็อต จะยังคงอยู่เพราะมันเป็นการปักหมุดแยกต่างหากที่เรียกซ้ำผ่านไดเรกทอรี

การสแนปช็อตซ้ำ

การสแนปช็อตซ้ำของโฟลเดอร์ที่ไม่เปลี่ยนแปลงจะส่งคืน CID เดิม — directory CID เป็นแบบ content-addressed ดังนั้นเนื้อหาที่เหมือนกันจะให้แฮชเดียวกันเสมอ และการเรียกปักหมุดของคลัสเตอร์จะรู้จำรายการซ้ำและไม่ทำอะไรเพิ่มในฝั่งของมัน

หมายเหตุ: เส้นทางสแนปช็อตเองไม่ได้ฟรีแม้ผลลัพธ์จะเป็น CID เดิม แต่ละครั้งจะอ่านไบต์ของทุกไฟล์กลับจาก IPFS และอัปโหลดซ้ำเป็น multipart ไปยัง endpoint /add ของคลัสเตอร์ — นั่นคือจุดที่การห่อด้วยไดเรกทอรีเกิดขึ้น สำหรับโฟลเดอร์ทั่วไป (≤100 ไฟล์เล็ก) ยังคงเสร็จภายในไม่กี่วินาที; สำหรับโฟลเดอร์ขนาดใหญ่มากควรเรียกสแนปช็อตเฉพาะเมื่อเนื้อหาเปลี่ยนแปลงจริง

การเรียกสแนปช็อตหลังจากที่คุณเพิ่มหรือลบไฟล์จะให้ CID ที่แตกต่างกัน CID เดิมจะยังคงแก้ไขได้ตราบใดที่คุณไม่ลบไฟล์ที่เป็นพื้นฐานของมัน

ขีดจำกัด

  • โฟลเดอร์ต้องมีอย่างน้อยหนึ่งไฟล์ โฟลเดอร์ว่างจะส่งคืน 400 — folder is empty
  • ตัวอักษรในชื่อไฟล์จะถูก URL-encode ในการอัปโหลดแบบ multipart ที่ Kubo รับ; URL ของ gateway อาจต้อง percent-encode สำหรับช่องว่างหรือตัวอักษรที่ไม่ใช่ ASCII ในชื่อไฟล์ของคุณ
  • สแนปช็อตจะนับรวมในโควตาการปักหมุดของแผนคุณเพียงครั้งเดียวต่อ CID ที่ไม่ซ้ำกัน — บล็อกของไฟล์จะถูก deduplicate ดังนั้นสแนปช็อตส่วนใหญ่จะเพิ่มเพียงโหนดไดเรกทอรีขนาดเล็กบนไฟล์ที่คุณปักหมุดอยู่แล้ว

อัปเดตโฟลเดอร์

PUT /folders/{folderId}

พารามิเตอร์ประเภทจำเป็นคำอธิบาย
namestringไม่ชื่อที่แสดงใหม่
parentFolderIdstring | nullไม่เปลี่ยนโฟลเดอร์แม่ null ย้ายไปที่ราก

ลบโฟลเดอร์

DELETE /folders/{folderId}

ลบโฟลเดอร์และไล่ระดับผ่านทุกไฟล์และโฟลเดอร์ย่อยที่มีอยู่ในนั้นแบบเรียกซ้ำ อยู่ภายใต้การป้องกันความปลอดภัยสำหรับ CID ที่ใช้ร่วมกันเช่นเดียวกับการลบไฟล์แต่ละไฟล์ — หากผู้ใช้อื่นยังปักหมุด CID ที่คุณอัปโหลดอยู่ การถอนปักหมุดของคุณจะไม่ลบมันสำหรับพวกเขา

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

กำหนดค่า S3 CORS สำหรับโฟลเดอร์ / bucket

โฟลเดอร์ที่เปิดเผยผ่าน S3-compatible API ทำหน้าที่เป็น bucket หากคุณขับเคลื่อน API นั้นจาก JavaScript บนเบราว์เซอร์ คุณต้องมีกฎ CORS บน bucket เพื่อให้ preflight ของเบราว์เซอร์ผ่าน มีพื้นผิวที่เทียบเท่ากันสองอย่างที่บันทึกไปยัง store เดียวกัน:

  • PUT /folders/{folderId}/cors — REST endpoint นี้ ยืนยันตัวตนด้วย JWT (ใช้โดยแดชบอร์ด)
  • S3 subresource PUT /{bucket}?cors — ยืนยันตัวตนด้วย SigV4 (ใช้โดย AWS SDK, ดู s3-compatibility.md)

PUT บน endpoint นี้ยังจองชื่อของโฟลเดอร์เป็น bucket ที่ไม่ซ้ำกันทั่วโลกหากยังไม่เคยถูกจอง

PUT /folders/{folderId}/cors

ตั้งค่ากฎ CORS สำหรับ S3 bucket ของโฟลเดอร์ สูงสุด 5 กฎต่อ bucket, รวม 64 KB

พารามิเตอร์ประเภทจำเป็นคำอธิบาย
rulesCorsRule[]ใช่อาร์เรย์ของกฎ CORS รูปแบบ AWS (ดูด้านล่าง) ต้องไม่ว่าง
bucketNamestringไม่ชื่อ S3 bucket ที่ระบุชัดเจน ค่าเริ่มต้นคือชื่อที่แสดงของโฟลเดอร์ หากชื่อที่ต้องการถูกจองไปแล้วทั่วโลก ให้ส่งชื่ออื่นที่นี่

แต่ละ CorsRule:

ฟิลด์ประเภทจำเป็นคำอธิบาย
AllowedOriginsstring[]ใช่origin ที่อนุญาตให้ส่งคำขอ รองรับ wildcard (https://*.myapp.com) ใช้ * สำหรับ origin ใดก็ได้
AllowedMethodsstring[]ใช่หนึ่งรายการขึ้นไปของ GET, HEAD, PUT, POST, DELETE
AllowedHeadersstring[]ไม่เฮดเดอร์ที่เบราว์เซอร์อาจรวมในคำขอ ค่าเริ่มต้น: ไม่มี ใช้ ["*"] เพื่ออนุญาตทั้งหมด (แนะนำสำหรับ AWS SDK v3 ซึ่งส่ง Authorization, x-amz-* เป็นต้น)
ExposeHeadersstring[]ไม่เฮดเดอร์การตอบกลับที่ทำให้ JavaScript ในเบราว์เซอร์อ่านได้ รวม ETag และ x-amz-meta-cid หากแอปของคุณต้องการ CID ที่ส่งคืน
MaxAgeSecondsnumberไม่ระยะเวลาที่เบราว์เซอร์แคช preflight 0-86400 ค่าเริ่มต้น 3600
IDstringไม่ป้ายกำกับแบบข้อความอิสระสำหรับกฎ

ตัวอย่างคำขอ

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
    }]
  }'

การตอบกลับ 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

ส่งคืนกฎ CORS ปัจจุบันพร้อมชื่อ bucket (ถ้าถูกจองแล้ว)

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

DELETE /folders/{folderId}/cors

ลบกฎ CORS ทั้งหมด preflight ของเบราว์เซอร์ต่อ bucket จะล้มเหลวแบบปิดจนกว่าจะตั้งกฎใหม่

ทางเลือกในแดชบอร์ด

บนหน้า Files เมนูการกระทำของแต่ละโฟลเดอร์มีรายการ S3 CORS ที่เปิดตัวแก้ไขแบบฟอร์ม store พื้นฐานเดียวกับ REST endpoint นี้และกับ PutBucketCors ผ่าน S3 API