Skip to content

フォルダ

フォルダは、ダッシュボード内でアップロードしたファイルを整理するためのものです。デフォルトではメタデータのみです — ファイルはそれぞれ自身の CID を保持し、IPFS 上で移動するわけではありません — ただし、フォルダをスナップショットすることで、実際の UnixFS ディレクトリとして実体化し、フォルダ全体に対して 1 つの CID を取得することもできます。

フォルダをスナップショットするタイミング

フォルダスナップショットは、フォルダ内のすべてのファイルを名前でアドレス指定可能な形で含む、単一の IPFS ディレクトリ CID です。これを使うと、次のようなことができます。

  • フォルダ全体を 1 つの URL で共有する: https://ipfs.ninja/ipfs/{dirCid}/
  • https://ipfs.ninja/ipfs/{dirCid}/photo.jpg(または他の任意の gateway)を直接解決する
  • CID を ENS の contenthash に設定して静的サイトをホストする
  • NFT コレクションのベース CID として使用し、各トークンが ipfs://{dirCid}/<id>.json を参照するようにする
  • ディレクトリを他の場所にピン留めする — 世界中のあらゆる IPFS gateway が UnixFS のディレクトリ CID を解決する方法を知っています

スナップショットはコンテンツアドレス方式です。フォルダの内容が同一であれば、常に同じ CID が生成されます。変更していないフォルダを再度スナップショットすると、以前と同じ CID が返されます。ファイルの追加・削除・リネームを行うと新しい CID が生成されます。以前の CID は、そのファイルを削除しない限り、引き続きピン留めされ解決可能な状態を保ちます。

フォルダの作成

POST /folders

ParameterTypeRequiredDescription
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

ParameterTypeRequiredDescription
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 ディレクトリ CID の取得)

POST /folders/{folderId}/snapshot

フォルダを IPFS クラスター上に実際の UnixFS ディレクトリとして実体化し、その結果をピン留めします。フォルダ全体に対して 1 つの 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 gateway 経由で解決できます。最もシンプルな URL パターンは次のとおりです。

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

クラスターは再帰的にピン留めするため、子要素も解決可能です — 後でアカウントから元のファイルを削除した場合でも、スナップショットのコピーはディレクトリを再帰的に辿る別のピンとして存在するため、そのまま残ります。

再スナップショット

変更されていないフォルダを再度スナップショットしても、同じ CID が返されます — ディレクトリ CID はコンテンツアドレス方式であるため、同一の内容は常に同じハッシュを生成し、クラスターのピン留め呼び出しは重複を認識してその側では何も行いません(no-op)。

注: 結果が同じ CID であっても、スナップショットの処理自体は無料ではありません。呼び出しのたびに、すべてのファイルのバイトを IPFS から読み戻し、クラスターの /add エンドポイントにマルチパートとして再アップロードします — ここでディレクトリによるラップ処理が行われます。一般的なフォルダ(100 個以下の小さなファイル)であれば、この処理は数秒で完了しますが、非常に大きなフォルダでは、内容が実際に変更された場合にのみスナップショットを呼び出すことをお勧めします。

ファイルを追加または削除した後にスナップショットを呼び出すと、異なる CID が生成されます。以前の CID は、その基になるファイルを削除しない限り、引き続き解決可能です。

制限

  • フォルダには少なくとも 1 つのファイルが含まれている必要があります。空のフォルダは 400 — folder is empty を返します。
  • ファイル名の文字は、Kubo が受け付けるマルチパートアップロード内で URL エンコードされます。gateway の URL では、ファイル名にスペースや非 ASCII 文字が含まれる場合、パーセントエンコーディングが必要になることがあります。
  • スナップショットは、ユニークな CID ごとにちょうど 1 回、プランのピン留め合計にカウントされます — ファイルのブロックは重複排除されるため、スナップショットは基本的に、すでにピン留めされているファイルの上に小さなディレクトリノードを追加するだけです。

フォルダの更新

PUT /folders/{folderId}

ParameterTypeRequiredDescription
namestringいいえ新しい表示名。
parentFolderIdstring | nullいいえフォルダの親を変更します。null を指定するとルートに移動します。

フォルダの削除

DELETE /folders/{folderId}

フォルダを削除し、含まれるすべてのファイルとサブフォルダに再帰的にカスケードします。個別のファイル削除と同じ共有 CID の安全ガードが適用されます — 他のユーザーがあなたのアップロードした CID を引き続きピン留めしている場合、あなたのアンピンによって彼らからその CID が失われることはありません。

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

フォルダ / bucket の S3 CORS を設定する

S3 互換 API を通じて公開されるフォルダは bucket として機能します。ブラウザの JavaScript からその API を操作する場合、ブラウザのプリフライトを通過させるために bucket に CORS ルールを設定する必要があります。同じストアに永続化する、同等の 2 つの手段があります。

  • PUT /folders/{folderId}/cors — この REST endpoint、JWT 認証(dashboard で使用)
  • S3 サブリソース PUT /{bucket}?cors — SigV4 認証(AWS SDK で使用、s3-compatibility.md を参照

この endpoint への PUT は、まだ取得されていない場合、フォルダの名前をグローバルに一意な bucket として取得もします。

PUT /folders/{folderId}/cors

フォルダの S3 bucket に対する CORS ルールを設定します。bucket あたり最大 5 ルール、合計 64 KB まで。

ParameterTypeRequiredDescription
rulesCorsRule[]はいAWS 形式の CORS ルールの配列(下記参照)。空にはできません。
bucketNamestringいいえ明示的な S3 bucket 名。デフォルトはフォルダの表示名です。希望する名前がすでにグローバルに取得されている場合は、ここに別の名前を指定してください。

CorsRule:

FieldTypeRequiredDescription
AllowedOriginsstring[]はいリクエストの送信を許可する Origin。ワイルドカード(https://*.myapp.com)に対応しています。任意の Origin を許可する場合は * を使用します。
AllowedMethodsstring[]はいGETHEADPUTPOSTDELETE のうち 1 つ以上。
AllowedHeadersstring[]いいえブラウザがリクエストに含めることを許可するヘッダー。デフォルト: なし。すべて許可する場合は ["*"] を使用します(Authorizationx-amz-* などを送信する AWS SDK v3 では推奨)。
ExposeHeadersstring[]いいえブラウザの JavaScript から読み取り可能にするレスポンスヘッダー。アプリが返された CID を必要とする場合は**ETagx-amz-meta-cid を含めてください**。
MaxAgeSecondsnumberいいえブラウザがプリフライトをキャッシュする時間。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 ルールを削除します。新しいルールが設定されるまで、bucket に対するブラウザのプリフライトは失敗するようになります。

Dashboard での代替方法

Files ページでは、各フォルダのアクションメニューに S3 CORS という項目があり、フォーム形式のエディタが開きます。この REST endpoint や、S3 API 経由の PutBucketCors と同じ基盤ストアを使用します。