Skip to content

폴더

폴더는 대시보드에서 업로드한 파일을 정리합니다. 기본적으로 메타데이터 전용입니다 — 파일은 각자의 CID를 유지하며 IPFS 상에서 이동되지 않습니다 — 하지만 폴더를 스냅샷하여 실제 UnixFS 디렉터리로 구체화하고 전체에 대한 CID 하나를 얻을 수도 있습니다.

폴더를 스냅샷해야 할 때

폴더 스냅샷은 폴더 안의 모든 파일을 이름으로 주소 지정 가능하게 담고 있는 단일 IPFS 디렉터리 CID입니다. 이를 통해 다음이 가능합니다:

  • 하나의 URL로 폴더 전체를 공유: https://ipfs.ninja/ipfs/{dirCid}/
  • https://ipfs.ninja/ipfs/{dirCid}/photo.jpg (또는 다른 게이트웨이)를 직접 해석
  • CID를 ENS contenthash에 넣어 정적 사이트 호스팅
  • NFT 컬렉션의 기본 CID로 사용하여 각 토큰이 ipfs://{dirCid}/<id>.json을 참조하도록 함
  • 디렉터리를 어디든 다른 곳에 피닝 — 전 세계 모든 IPFS 게이트웨이가 UnixFS 디렉터리 CID를 해석하는 방법을 알고 있음

스냅샷은 콘텐츠 주소 지정 방식입니다: 동일한 폴더 내용은 항상 동일한 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 디렉터리 CID 얻기)

POST /folders/{folderId}/snapshot

폴더를 IPFS 클러스터상의 실제 UnixFS 디렉터리로 구체화하고 결과를 피닝합니다. 폴더 전체에 대해 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에서 모든 파일의 바이트를 다시 읽어와 클러스터의 /add 엔드포인트로 멀티파트로 재업로드합니다 — 여기서 디렉터리 래핑이 이루어집니다. 일반적인 폴더(파일 100개 이하의 소규모)라면 여전히 몇 초 안에 완료되지만, 매우 큰 폴더의 경우 콘텐츠가 실제로 변경되었을 때만 스냅샷을 호출하는 것이 좋습니다.

파일을 추가하거나 제거한 후 스냅샷을 호출하면 다른 CID가 생성됩니다. 이전 CID는 그 기반이 되는 파일을 삭제하지 않는 한 계속 해석됩니다.

제한 사항

  • 폴더에는 파일이 하나 이상 있어야 합니다. 빈 폴더는 400 — folder is empty를 반환합니다.
  • 파일 이름 문자는 Kubo가 받는 멀티파트 업로드에서 URL 인코딩됩니다. 파일 이름에 공백이나 비 ASCII 문자가 있으면 게이트웨이 URL에서 퍼센트 인코딩이 필요할 수 있습니다.
  • 스냅샷은 고유 CID당 정확히 한 번만 플랜의 핀 총량에 포함됩니다 — 파일 블록은 중복 제거되므로, 스냅샷은 이미 피닝된 파일 위에 작은 디렉터리 노드만 추가하는 경우가 대부분입니다.

폴더 업데이트

PUT /folders/{folderId}

매개변수유형필수설명
namestring아니요새 표시 이름.
parentFolderIdstring | null아니요폴더의 부모를 변경합니다. null은 루트로 이동합니다.

폴더 삭제

DELETE /folders/{folderId}

폴더와 그 안에 포함된 모든 파일 및 하위 폴더를 재귀적으로 삭제합니다. 개별 파일 삭제와 동일한 공유 CID 안전 가드가 적용됩니다 — 업로드한 CID를 다른 사용자가 여전히 피닝하고 있다면, 자신의 핀 해제가 그들에게서 CID를 제거하지는 않습니다.

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

폴더 / 버킷에 S3 CORS 구성

S3 호환 API를 통해 노출된 폴더는 버킷처럼 동작합니다. 브라우저 JavaScript에서 해당 API를 호출한다면, 브라우저 preflight가 통과하도록 버킷에 CORS 규칙이 필요합니다. 동일한 저장소에 지속되는 두 가지 동등한 경로가 있습니다:

  • PUT /folders/{folderId}/cors — 이 REST 엔드포인트, JWT 인증 (대시보드에서 사용)
  • S3 서브리소스 PUT /{bucket}?cors — SigV4 인증 (AWS SDK에서 사용, s3-compatibility.md 참조)

이 엔드포인트의 PUT은 아직 선점되지 않았다면 폴더의 이름을 전역적으로 고유한 버킷으로도 선점합니다.

PUT /folders/{folderId}/cors

폴더의 S3 버킷에 대한 CORS 규칙을 설정합니다. 버킷당 최대 5개 규칙, 총 64 KB.

매개변수유형필수설명
rulesCorsRule[]AWS 형태의 CORS 규칙 배열 (아래 참조). 비어 있지 않아야 함.
bucketNamestring아니요명시적인 S3 버킷 이름. 기본값은 폴더의 표시 이름입니다. 원하는 이름이 이미 전역적으로 선점되었다면 여기에 대안을 전달하세요.

CorsRule:

필드유형필수설명
AllowedOriginsstring[]요청을 보낼 수 있는 오리진. 와일드카드 지원(https://*.myapp.com). 모든 오리진을 허용하려면 * 사용.
AllowedMethodsstring[]GET, HEAD, PUT, POST, DELETE 중 하나 이상.
AllowedHeadersstring[]아니요브라우저가 요청에 포함할 수 있는 헤더. 기본값: 없음. 모두 허용하려면 ["*"] 사용(Authorization, x-amz-* 등을 보내는 AWS SDK v3에 권장).
ExposeHeadersstring[]아니요브라우저 JavaScript가 읽을 수 있는 응답 헤더. 앱이 반환된 CID를 필요로 한다면 ETagx-amz-meta-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 규칙과 버킷 이름(선점된 경우)을 반환합니다.

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

DELETE /folders/{folderId}/cors

모든 CORS 규칙을 제거합니다. 새 규칙이 설정될 때까지 버킷에 대한 브라우저 preflight는 차단 상태(fail closed)가 됩니다.

대시보드 대안

파일 페이지에서 각 폴더의 작업 메뉴에는 폼 기반 편집기를 여는 S3 CORS 항목이 있습니다. 이 REST 엔드포인트 및 S3 API의 PutBucketCors와 동일한 기본 저장소를 사용합니다.