Skip to content

Папки ​

Папки организуют ваши загруженные файлы в панели управления. По умолчанию они хранят только метаданные — файлы сохраняют собственные CID и не перемещаются в IPFS — но вы также можете сделать снимок папки (snapshot), чтобы материализовать её как настоящую директорию UnixFS и получить один CID для всего содержимого.

Когда стоит делать снимок папки ​

Снимок папки — это единый CID директории IPFS, содержащий все файлы папки, адресуемые по имени. С его помощью вы можете:

  • Поделиться всей папкой по одной ссылке: https://ipfs.ninja/ipfs/{dirCid}/
  • Разрешать https://ipfs.ninja/ipfs/{dirCid}/photo.jpg (или через любой другой шлюз) напрямую
  • Поместить CID в contenthash ENS, чтобы разместить статический сайт
  • Использовать его как базовый CID коллекции NFT, чтобы каждый токен ссылался на ipfs://{dirCid}/<id>.json
  • Закрепить директорию где угодно ещё — любой шлюз IPFS в мире умеет разрешать CID директории UnixFS

Снимки адресуются по содержимому: одинаковое содержимое папки всегда даёт одинаковый 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-…" }'

Сделать снимок папки (получить CID директории UnixFS) ​

POST /folders/{folderId}/snapshot

Материализует папку как настоящую директорию UnixFS в кластере IPFS и закрепляет результат. Возвращает один CID для всей папки. Имена дочерних элементов берутся из поля fileName каждого файла; дубликаты автоматически разрешаются без конфликтов.

Тело запроса не требуется; папка определяется параметром пути.

Пример ​

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 без необходимости повторного снимка.

Разрешение снимка ​

Как только снимок закреплён, CID директории разрешается через любой шлюз IPFS. Простейший шаблон URL:

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

Кластер закрепляет рекурсивно, поэтому дочерние элементы тоже разрешимы — даже если позже вы удалите исходный файл из своего аккаунта, копия из снимка сохранится, поскольку это отдельное закрепление, рекурсивно проходящее через директорию.

Повторные снимки ​

Повторный снимок неизменённой папки возвращает тот же CID — CID директорий адресуются по содержимому, поэтому одинаковое содержимое всегда даёт одинаковый хеш, а вызов закрепления в кластере распознаёт дубликат и не выполняет никаких действий на своей стороне.

Обратите внимание: сам процесс снимка не бесплатен, даже если результат — тот же CID. Каждый вызов заново считывает байты каждого файла из IPFS и повторно загружает их как multipart на endpoint /add кластера — именно там происходит обёртывание в директорию. Для типичных папок (≤100 небольших файлов) это всё ещё занимает несколько секунд; для очень больших папок предпочтительно вызывать снимок только тогда, когда содержимое действительно изменилось.

Вызов снимка после добавления или удаления файлов даёт другой CID; предыдущий продолжает разрешаться, пока вы не удалите его исходные файлы.

Ограничения ​

  • Папка должна содержать хотя бы один файл. Пустые папки возвращают 400 — folder is empty.
  • Символы имён файлов кодируются URL-кодированием в multipart-загрузке, принимаемой Kubo; URL шлюза могут потребовать процентного кодирования для пробелов или не-ASCII символов в именах файлов.
  • Снимки учитываются в общем лимите закреплений вашего плана ровно один раз для каждого уникального CID — блоки файлов дедуплицируются, поэтому снимок в основном добавляет лишь небольшой узел директории поверх файлов, которые вы уже закрепили.

Обновить папку ​

PUT /folders/{folderId}

ПараметрТипОбязательныйОписание
namestringНетНовое отображаемое имя.
parentFolderIdstring | nullНетПереместить папку к новому родителю. null перемещает её в корень.

Удалить папку ​

DELETE /folders/{folderId}

Удаляет папку и рекурсивно каскадно проходит по всем файлам и вложенным папкам, которые она содержит. Действует та же защита совместно используемых CID, что и при удалении отдельных файлов — если другие пользователи всё ещё закрепляют загруженный вами CID, ваше открепление не удаляет его для них.

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

Настройка S3 CORS для папки / bucket-а ​

Папки, доступные через S3-совместимый API, выступают в роли bucket-ов. Если вы работаете с этим API из браузерного JavaScript, вам нужны правила CORS на bucket-е, чтобы preflight-запросы браузера проходили успешно. Есть два эквивалентных интерфейса, сохраняющих данные в одно и то же хранилище:

  • PUT /folders/{folderId}/cors — этот REST endpoint, аутентификация через JWT (используется панелью управления)
  • S3-субресурс 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[]ДаИсточники, которым разрешено отправлять запросы. Поддерживает подстановочные знаки (https://*.myapp.com). Используйте * для любого источника.
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-у будут отклоняться, пока не будут заданы новые правила.

Альтернатива через панель управления

На странице «Файлы» в меню действий каждой папки есть пункт S3 CORS, открывающий редактор в виде формы. Использует то же самое хранилище, что и этот REST endpoint, и что PutBucketCors через API S3.