コンテンツにスキップ

共有マルチパートアップロードリファレンス

RealityConnect APIの複数のアップロードエンドポイントは、同じ基本パターンを共有しています。アップロードを開始し、ファイルを1つ以上の署名付きURLへ直接**アップロード(PUT)**し、確定するというものです。このページは、このパターン、パート番号ルール、アップロード中のリフレッシュ・再開・進捗確認についての共有リファレンスです。エンドポイント固有のガイドからは、この仕組みを繰り返す代わりにこのページへリンクしてください。


このパターンを使用するエンドポイント

Section titled “このパターンを使用するエンドポイント”
フロー開始確定パーツに分割?リフレッシュエンドポイント?
Data BundleアップロードPOST /v1/bundles/{bundleId}/upload-sessions/{sessionId}/filesPOST .../files/{fileId}/finalizeありあり
オブジェクトの添付ファイルPOST /v1/twin/{contextId}/object/attachmentsPOST .../attachments/{fileId}/finalizeありあり
サイトファイルPOST /v1/site-filesPOST /v1/site-files/{fileId}/finalizeありなし
アセットライブラリモデルPOST /v1/asset-library/{ownerContextId}/modelsPOST .../models/{libraryModelId}/finalizeなし(単一ファイル)なし
ノードのサムネイルPOST /v1/nodes/{nodeId}/thumbnailPOST /v1/nodes/{nodeId}/thumbnail/{uploadId}/finalizeなし(単一ファイル)なし

開始・アップロード・確定の流れ

Section titled “開始・アップロード・確定の流れ”
sequenceDiagram
  participant Client as Client
  participant RCAPI as RCAPI
  participant S3 as S3

  Client->>RCAPI: POST initiate
  RCAPI-->>Client: fileId/uploadId + 署名付きURL
  loop for each part
    Client->>S3: PUT part
    S3-->>Client: ETag
  end
  Client->>RCAPI: POST finalize (ETagを含む)
  RCAPI-->>Client: アップロード完了
  1. 開始: ファイル名とサイズ(およびData Bundleファイルのtypeなど、フロー固有のフィールド)を指定して、フローの開始エンドポイントを呼び出します。レスポンスには、確定に使用する識別子と、ファイルをPUTする1つ以上の署名付きS3 urlが返されます。
  2. アップロード: ファイルのバイトデータを、返されたURLへ直接PUTします。これらのリクエストにはAuthorizationヘッダーは付与されません。URL自体がすでに署名済みだからです。各PUTのレスポンスのETagヘッダーを保持しておいてください。
  3. 確定: 収集したETagを指定して、フローの確定エンドポイントを呼び出し、アップロードを完了させます。

アセットライブラリモデルとノードのサムネイルは、現状では1回のPUTで単一ファイルのみを受け付けるため、URLは1つ、ETagも1つで、partNumberはまったく存在しません。この2つは、同じパターンの単純な単一パーツのケースとして扱ってください。

これは、リフレッシュに対応する2つのフローに当てはまります。

実践例。 開始が3つのパーツを返したとします。

{
"urls": [
{ "partNumber": 1, "url": "https://s3…/part-1?…" },
{ "partNumber": 2, "url": "https://s3…/part-2?…" },
{ "partNumber": 3, "url": "https://s3…/part-3?…" }
]
}

partNumber: 2からリフレッシュするには、1を引いてstartIndex = 1でリフレッシュを呼び出します。

GET {api_url}/.../refresh/1

レスポンスのstartIndexには1が反映され、urlsには再び2から始まる1始まりのpartNumberが含まれます。

{ "startIndex": 1, "urls": [ { "partNumber": 2, "url": "…" }, { "partNumber": 3, "url": "…" } ] }

partNumberをそのまま(1ではなく2として)startIndexに渡してしまうと、パーツ2がスキップされ、パーツ3以降しかリフレッシュされません。

アップロード中に期限切れとなった署名付きURLをリフレッシュする

Section titled “アップロード中に期限切れとなった署名付きURLをリフレッシュする”

署名付きPUT URLには有効期限があります。アップロードが長時間に及び、あるパーツのPUTが403を返し始めた場合は、その時点で止まっていたパーツを対象に(startIndex = partNumber - 1として)リフレッシュエンドポイントを呼び出してください。リフレッシュはそのパーツとそれ以降のすべてのパーツの新しいURLを返します。パーツごとに個別にリフレッシュする必要はなく、ファイルを再度開始する必要もありません。

リフレッシュは次のフローで利用できます。

  • Data Bundleアップロード: GET /v1/bundles/{bundleId}/upload-sessions/{sessionId}/files/{fileId}/refresh/{startIndex}
  • オブジェクトの添付ファイル: GET /v1/twin/{contextId}/object/attachments/{fileId}/refresh/{startIndex}

サイトファイル、アセットライブラリモデル、ノードのサムネイルにはリフレッシュエンドポイントがありません。これらのフローでアップロード中にURLが期限切れになった場合は、ファイルを再度開始して新しいURLを取得してください。

中断したアップロードを再開し、進捗を確認する

Section titled “中断したアップロードを再開し、進捗を確認する”

再開の方法と進捗の確認方法は、フローによって異なります。

  • Data Bundleアップロードは、セッション単位で進捗を追跡します。Bundleのアップロードセッションを一覧表示し(GET /v1/bundles/{bundleId}/upload-sessions)、finalizedFileCountをexpectedFileCountと比較してください。再開する際は、まだ完了していないファイルのみを、確定済みとして現れていないtypeとfileNameに基づいて開始・確定してください。
  • オブジェクトの添付ファイル、サイトファイル、アセットライブラリモデル、ノードのサムネイルは、確認できるセッションや一覧を持たない単一ファイルの操作です。進捗は、取得したfileId(またはuploadId)に対して確定がすでに成功しているかどうかだけで判断します。アセットライブラリモデルについては、モデル自身のstatusフィールドでも確認でき、確定が完了するまではuploadingのままです。これらのいずれかを中断後に再開するには、開始時に受け取った識別子を保持したうえで、残りのパーツのアップロードを続ける(可能な場合は必要に応じてURLをリフレッシュする)か、識別子やそのURLがもう使用できない場合は再度開始してください。

ストレージ容量の上限と、既存ファイルへの再アップロード

Section titled “ストレージ容量の上限と、既存ファイルへの再アップロード”

アップロードの開始は、リクエスト自体が不正な場合、データが1バイトも送信される前に拒否されることがあります。最も一般的なのは、組織のストレージ容量がすでに上限に達している場合のStorageLimitExceededと、同一の識別情報を持つファイルへ再アップロードしようとした場合のFileAlreadyExistsです。これらはレスポンス本文に含まれる名前付きエラーコードであり、エンドポイントごとの正確なステータスコードとともにエラーコード: ファイルアップロードにまとめられています。

  • エンドポイントごとのStorageLimitExceededやFileAlreadyExistsを含む、名前付きエラーコードの一覧についてはエラーコードを参照してください。
  • このパターンの最も詳細な実践例として、再開可能なバッチアップロードを含むData Bundleへのデータアップロードを参照してください。