Box Developerドキュメント

項目のメタデータの更新

項目のメタデータの更新

ファイルまたはフォルダに適用されたメタデータを更新するには、項目のid、テンプレートのtemplateKeyscopeに加え、テンプレートインスタンスのデータを操作するための一連のJSON操作を使用します。

ファイルのメタデータの更新

ファイルのメタデータを更新するには、ファイルのfile_id、テンプレートのscopetemplateKey、およびテンプレートインスタンスのデータを操作するための一連のJSON操作を指定してPUT /files/:file_id/metadata/:scope/:templateKey APIエンドポイントを呼び出します。

cURL
curl -i -X PUT "https://api.box.com/2.0/files/12345/metadata/enterprise_27335/blueprintTemplate" \
     -H "authorization: Bearer <ACCESS_TOKEN>" \
     -H "content-type: application/json-patch+json" \
     -d '[
        {
          "op": "test",
          "path": "/competitiveDocument",
          "value": "no"
        },
        {
          "op": "remove",
          "path": "/competitiveDocument"
        },
        {
          "op": "test",
          "path": "/status",
          "value": "active"
        },
        {
          "op": "replace",
          "path": "/status",
          "value": "inactive"
        },
        {
          "op": "test",
          "path": "/author",
          "value": "Jones"
        },
        {
          "op": "copy",
          "from": "/author",
          "path": "/editor"
        },
        {
          "op": "test",
          "path": "/currentState",
          "value": "proposal"
        },
        {
          "op": "move",
          "from": "/currentState",
          "path": "/previousState"
        },
        {
          "op": "add",
          "path": "/currentState",
          "value": "reviewed"
        }
      ]'
TypeScript Gen
await client.fileMetadata.updateFileMetadataById(
  file.id,
  'global' as UpdateFileMetadataByIdScope,
  'properties',
  [
    {
      op: 'replace' as UpdateFileMetadataByIdRequestBodyOpField,
      path: '/abc',
      value: newValue,
    } satisfies UpdateFileMetadataByIdRequestBody,
  ],
);
Python Gen
client.file_metadata.update_file_metadata_by_id(
    file.id,
    UpdateFileMetadataByIdScope.GLOBAL.value,
    "properties",
    [
        UpdateFileMetadataByIdRequestBody(
            op=UpdateFileMetadataByIdRequestBodyOpField.REPLACE.value,
            path="/abc",
            value=new_value,
        )
    ],
)
.NET Gen
await client.FileMetadata.UpdateFileMetadataByIdAsync(fileId: file.Id, scope: UpdateFileMetadataByIdScope.Global, templateKey: "properties", requestBody: Array.AsReadOnly(new [] {new UpdateFileMetadataByIdRequestBody() { Op = UpdateFileMetadataByIdRequestBodyOpField.Replace, Path = "/abc", Value = newValue }}));
Java
BoxFile file = new BoxFile(api, "id");
file.updateMetadata(new Metadata("templateScope", "templateKey").add("/foo", "bar"));
Python
file_obj = client.file(file_id='11111')
file_metadata = file_obj.metadata(scope='enterprise', template='myMetadata')

updates = file_metadata.start_update()
updates.add('/foo', 'bar')
updates.update('/baz', 'murp', old_value='quux')  # Ensure the old value was "quux" before updating to "murp"

updated_metadata = file_metadata.update(updates)
print('Updated metadata on file!')
print(f'foo is now {updated_metadata["foo"]} and baz is now {updated_metadata["baz"]}')
.NET
var updates = new List<BoxMetadataUpdate>()
{
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/competitiveDocument",
        Value = "no"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.remove,
        Path = "/competitiveDocument"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/status",
        Value = "active"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.replace,
        Path = "/competitiveDocument",
        Value = "inactive"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/author",
        Value = "Jones"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.copy,
        From="/author",
        Path = "/editor"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/currentState",
        Value = "proposal"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.move,
        From = "/currentState",
        Path = "/previousState"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.add,
        Path = "/currentState",
        Value = "reviewed"
    }
};
Dictionary<string, object> updatedMetadata = await client.MetadataManager
    .UpdateFileMetadataAsync("11111", updates, "enterprise", "marketingCollateral");
Node
var updates = [
	{ op: 'test', path: '/competitiveDocument', value: 'no' },
	{ op: 'remove', path: '/competitiveDocument' },
	{ op: 'test', path: '/status', value: 'active' },
	{ op: 'replace', path: '/status', value: 'inactive' },
	{ op: 'test', path: '/author', value: 'Jones' },
	{ op: 'copy', from: '/author', path: '/editor' },
	{ op: 'test', path: '/currentState', value: 'proposal' },
	{ op: 'move', from: '/currentState', path: '/previousState' },
	{ op: 'add', path: '/currentState', value: 'reviewed' }
];
client.files.updateMetadata('11111', client.metadata.scopes.ENTERPRISE, "marketingCollateral", updates)
	.then(metadata => {
		/* metadata -> {
			audience: 'internal',
			documentType: 'Q1 plans',
			status: 'inactive',
			author: 'Jones',
			'$type': 'marketingCollateral-d086c908-2498-4d3e-8a1f-01e82bfc2abe',
			'$parent': 'file_11111',
			'$id': '2094c584-68e1-475c-a581-534a4609594e',
			'$version': 1,
			'$typeVersion': 0,
			editor: 'Jones',
			previousState: 'proposal',
			currentState: 'reviewed',
			'$template': 'marketingCollateral',
			'$scope': 'enterprise_12345' }
		*/
	});
iOS
client.metadata.update(
    forFileWithId: "11111",
    scope: "enterprise",
    templateKey: "personnelRecord",
    operations: [
        .test(path: "/department", value: "Sales"),
        .replace(path: "/department", value: "Marketing")
    ]
) { (result: Result<MetadataObject, BoxSDKError>) in
    guard case let .success(metadata) = result {
        print("Error updating metadata")
        return
    }

    print("Employee department updated to \(metadata.keys["department"])")
}

認証済みユーザーがファイルのメタデータに対する変更を書き込めるようにするには、ファイルへの書き込みアクセス権限が必要です。

フォルダのメタデータを更新

フォルダのメタデータを更新するには、フォルダのfolder_id、テンプレートのscopetemplateKey、およびテンプレートインスタンスのデータを操作するための一連のJSON操作を指定してPUT /folders/:folder_id/metadata/:scope/:templateKey APIエンドポイントを呼び出します。

cURL
curl -i -X PUT "https://api.box.com/2.0/folders/4353455/metadata/enterprise_27335/blueprintTemplate" \
     -H "authorization: Bearer <ACCESS_TOKEN>" \
     -H "content-type: application/json-patch+json" \
     -d '[
        {
          "op": "test",
          "path": "/competitiveDocument",
          "value": "no"
        },
        {
          "op": "remove",
          "path": "/competitiveDocument"
        },
        {
          "op": "test",
          "path": "/status",
          "value": "active"
        },
        {
          "op": "replace",
          "path": "/status",
          "value": "inactive"
        },
        {
          "op": "test",
          "path": "/author",
          "value": "Jones"
        },
        {
          "op": "copy",
          "from": "/author",
          "path": "/editor"
        },
        {
          "op": "test",
          "path": "/currentState",
          "value": "proposal"
        },
        {
          "op": "move",
          "from": "/currentState",
          "path": "/previousState"
        },
        {
          "op": "add",
          "path": "/currentState",
          "value": "reviewed"
        }
      ]'
TypeScript Gen
await client.folderMetadata.updateFolderMetadataById(
  folder.id,
  'global' as UpdateFolderMetadataByIdScope,
  'properties',
  [
    {
      op: 'replace' as UpdateFolderMetadataByIdRequestBodyOpField,
      path: '/abc',
      value: newValue,
    } satisfies UpdateFolderMetadataByIdRequestBody,
  ],
);
Python Gen
client.folder_metadata.update_folder_metadata_by_id(
    folder.id,
    UpdateFolderMetadataByIdScope.GLOBAL.value,
    "properties",
    [
        UpdateFolderMetadataByIdRequestBody(
            op=UpdateFolderMetadataByIdRequestBodyOpField.REPLACE.value,
            path="/abc",
            value=new_value,
        )
    ],
)
.NET Gen
await client.FolderMetadata.UpdateFolderMetadataByIdAsync(folderId: folder.Id, scope: UpdateFolderMetadataByIdScope.Global, templateKey: "properties", requestBody: Array.AsReadOnly(new [] {new UpdateFolderMetadataByIdRequestBody() { Op = UpdateFolderMetadataByIdRequestBodyOpField.Replace, Path = "/abc", Value = newValue }}));
Java
BoxFolder folder = new BoxFolder(api, "id");
folder.updateMetadata(new Metadata().add("/foo", "bar"));
Python
folder = client.folder(folder_id='22222')
folder_metadata = folder.metadata(scope='enterprise', template='myMetadata')

updates = folder_metadata.start_update()
updates.add('/foo', 'bar')
updates.update('/baz', 'murp', old_value='quux')  # Ensure the old value was "quux" before updating to "murp"

updated_metadata = folder_metadata.update(updates)
print('Updated metadata on folder!')
print(f'foo is now {updated_metadata["foo"]} and baz is now {updated_metadata["baz"]}')
.NET
var updates = new List<BoxMetadataUpdate>()
{
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/competitiveDocument",
        Value = "no"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.remove,
        Path = "/competitiveDocument"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/status",
        Value = "active"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.replace,
        Path = "/competitiveDocument",
        Value = "inactive"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/author",
        Value = "Jones"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.copy,
        From="/author",
        Path = "/editor"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.test,
        Path = "/currentState",
        Value = "proposal"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.move,
        From = "/currentState",
        Path = "/previousState"
    },
    new BoxMetadataUpdate()
    {
        Op = MetadataUpdateOp.add,
        Path = "/currentState",
        Value = "reviewed"
    }
};
Dictionary<string, object> updatedMetadata = await client.MetadataManager
    .UpdateFolderMetadataAsync("11111", updates, "enterprise", "marketingCollateral");
Node
var updates = [
	{ op: 'test', path: '/competitiveDocument', value: 'no' },
	{ op: 'remove', path: '/competitiveDocument' },
	{ op: 'test', path: '/status', value: 'active' },
	{ op: 'replace', path: '/status', value: 'inactive' },
	{ op: 'test', path: '/author', value: 'Jones' },
	{ op: 'copy', from: '/author', path: '/editor' },
	{ op: 'test', path: '/currentState', value: 'proposal' },
	{ op: 'move', from: '/currentState', path: '/previousState' },
	{ op: 'add', path: '/currentState', value: 'reviewed' }
];
client.folders.updateMetadata('11111', client.metadata.scopes.ENTERPRISE, "marketingCollateral", updates)
	.then(metadata => {
		/* metadata -> {
			audience: 'internal',
			documentType: 'Q1 plans',
			status: 'inactive',
			author: 'Jones',
			'$type': 'marketingCollateral-d086c908-2498-4d3e-8a1f-01e82bfc2abe',
			'$parent': 'folder_11111',
			'$id': '2094c584-68e1-475c-a581-534a4609594e',
			'$version': 1,
			'$typeVersion': 0,
			editor: 'Jones',
			previousState: 'proposal',
			currentState: 'reviewed',
			'$template': 'marketingCollateral',
			'$scope': 'enterprise_12345' }
		*/
	});
iOS
client.metadata.update(
    forFolderWithId: "22222",
    scope: "enterprise",
    templateKey: "personnelRecord",
    operations: [
        .test(path: "/department", value: "Sales"),
        .replace(path: "/department", value: "Marketing")
    ]
) { (result: Result<MetadataObject, BoxSDKError>) in
    guard case let .success(metadata) = result {
        print("Error updating metadata")
        return
    }

    print("Employee department updated to \(metadata.keys["department"])")
}

認証済みユーザーがファイルのメタデータに対する変更を書き込めるようにするには、ファイルへの書き込みアクセス権限が必要です。

JSON操作

メタデータを更新する場合は、JSON-Patchの仕様に従う必要があります。これは、操作オブジェクトのリストとして表されます。

メタデータインスタンスの場合、これらの操作にはaddreplaceremovetestmovecopyのいずれかを指定できます。どの操作も、opの名前、変更対象のフィールドを指すJSON Pointer pathのほか、実行される操作に応じたvalueまたはfrom値 (省略可) で構成されます。

[
  { "op": "test", "path": "/competitiveDocument", "value": "no" },
  { "op": "remove", "path": "/competitiveDocument" },
  { "op": "test", "path": "/status", "value": "active" },
  { "op": "replace", "path": "/status", "value": "inactive" },
  { "op": "test", "path": "/author", "value": "Jones" },
  { "op": "copy", "from": "/author", "path": "/editor" },
  { "op": "move", "from": "/currentState", "path": "/previousState" },
  { "op": "add", "path": "/currentState", "value": "reviewed" }
]

メタデータを編集する際には、メタデータテンプレートのスキーマに準拠した値のみを使用できます。更新は完全に適用されるか、まったく適用されないかのどちらかです。更新操作の適用中にエラーが発生した場合、メタデータインスタンスは変更されません。

テンプレートインスタンスを更新できるのは、テンプレートがすでにファイルまたはフォルダに割り当てられている場合のみです。

新しい値の追加

テンプレートに新しい値を追加するには、add操作を使用します。

[
  {
    "op": "add",
    "path": "/name",
    "value": "Model 3"
  }
]

これにより、値がModel 3nameフィールドが追加されます。この操作の前は、テンプレートのnameフィールドに値がありませんでした。

{
  // "name": null, // old value
  "name": "Model 3", // new value
  "category": "SUVs",
  "$type": "productInfo-8120731a-41e4-11ea-b77f-2e728ce88125",
  "$parent": "folder_3456",
  "$id": "22ba8c96-41e6-11ea-b77f-2e728ce88125",
  "$version": 3,
  "$typeVersion": 0,
  "$template": "productInfo",
  "$scope": "enterprise_1234567",
  "$canEdit": true
}

enumおよびmultiSelectフィールドの場合、この新しい値には、そのフィールドに有効なオプションのいずれかを指定する必要があります。

値の置き換え

テンプレート上の値を置き換えるには、replace操作を使用します。

[
  {
    "op": "replace",
    "path": "/name",
    "value": "Model 4"
  }
]

これにより、nameフィールドの値Model 3が新しい値Model 4に置き換えられます。

{
  // "name": "Model 3", # Old value
  "name": "Model 3", // new value
  "category": "SUVs",
  "$type": "productInfo-8120731a-41e4-11ea-b77f-2e728ce88125",
  "$parent": "folder_3456",
  "$id": "22ba8c96-41e6-11ea-b77f-2e728ce88125",
  "$version": 3,
  "$typeVersion": 0,
  "$template": "productInfo",
  "$scope": "enterprise_1234567",
  "$canEdit": true
}

enumおよびmultiSelectフィールドの場合、この新しい値には、そのフィールドに有効なオプションのいずれかを指定する必要があります。

値のコピー

値をあるフィールドから別のフィールドにコピーするには、copy操作を使用します。

[
  {
    "op": "copy",
    "from": "/name",
    "path": "/displayName"
  }
]

これにより、nameフィールドの値と一致する値が設定されたdisplayNameフィールドが追加されます。この操作の前は、テンプレートのdisplayNameフィールドに値がありませんでした。

{
  "name": "Model 3",
  "displayName": "Model 3", // new value, copied from the name
  "category": "SUVs",
  "$type": "productInfo-8120731a-41e4-11ea-b77f-2e728ce88125",
  "$parent": "folder_3456",
  "$id": "22ba8c96-41e6-11ea-b77f-2e728ce88125",
  "$version": 3,
  "$typeVersion": 0,
  "$template": "productInfo",
  "$scope": "enterprise_1234567",
  "$canEdit": true
}

enumおよびmultiSelectフィールドの場合、この新しい値には、そのフィールドに有効なオプションのいずれかを指定する必要があります。

値の移動

値をあるフィールドから別のフィールドに移動するには、move操作を使用します。

[
  {
    "op": "copy",
    "from": "/name",
    "path": "/displayName"
  }
]

これにより、nameフィールドの値と一致する値が設定されたdisplayNameフィールドが追加されます。この操作の前は、テンプレートのdisplayNameフィールドに値がありませんでした。この操作の後、nameフィールドはすでに存在しません。

{
  // "name": "Model 3", // old value, no longer present now
  "displayName": "Model 3", // new value, copied from the name
  "category": "SUVs",
  "$type": "productInfo-8120731a-41e4-11ea-b77f-2e728ce88125",
  "$parent": "folder_3456",
  "$id": "22ba8c96-41e6-11ea-b77f-2e728ce88125",
  "$version": 3,
  "$typeVersion": 0,
  "$template": "productInfo",
  "$scope": "enterprise_1234567",
  "$canEdit": true
}

enumおよびmultiSelectフィールドの場合、この新しい値には、そのフィールドに有効なオプションのいずれかを指定する必要があります。

値の削除

メタデータインスタンスから値を削除するには、remove操作を使用します。

[
  {
    "op": "remove",
    "path": "/name"
  }
]

これにより、nameフィールドがメタデータインスタンスから完全に削除されます。

{
  // "name": "Model 3", // old value, no longer present now
  "category": "SUVs",
  "$type": "productInfo-8120731a-41e4-11ea-b77f-2e728ce88125",
  "$parent": "folder_3456",
  "$id": "22ba8c96-41e6-11ea-b77f-2e728ce88125",
  "$version": 3,
  "$typeVersion": 0,
  "$template": "productInfo",
  "$scope": "enterprise_1234567",
  "$canEdit": true
}

enumおよびmultiSelectフィールドの場合、この新しい値には、そのフィールドに有効なオプションのいずれかを指定する必要があります。

値のテスト

フィールドに期待する値が設定されていることをテストするには、test操作を使用します。

[
  {
    "op": "test",
    "path": "/name",
    "value": "Model 4"
  }
]

テストに失敗すると、APIはいずれの操作も実行せず、次のエラーとともにHTTPステータス409 Conflictを返します。

{
  "message": "value differs from expectations",
  "code": "failed_json_patch_application",
  "request_id": "bzxgr1gbcq5h67pj"
}

この操作の主な目的は、何らかの操作が実行される前に、メタデータインスタンスの値が予想どおりであることを確認することです。Box APIでは、変更がすべて実行されるかまったく実行されないかのいずれかであるため、テストの失敗は、変換が適用される前にすべての値が予想どおりかどうかを確認するのに非常に役立ちます。