Custom Metadata records can be created, updated and deleted synchronously using Apex web services. This is simpler and more responsive for interactive scenarios, instead of using the native utility which requires asynchronous callback handlers.
This custom class supports the creation of Custom Metadata records from Apex code. It calls the Metadata API synchronously with immediate results for each record.
Example usage:
First paste the CustomMetadataClient.cls into your org.
Then call the methods to manipulate MDT records.
Unit tests here: CustomMetadataClientTest.cls
//create a metadata record Database.UpsertResult result = CustomMetadataClient.upsertMetadata( Custom__mdt.SObjectType, new Map<SObjectField,Object>{ Custom__mdt.DeveloperName => 'Developer_Name', Custom__mdt.MasterLabel => 'Master Label', Custom__mdt.Position__c => 3 } );
//delete a metadata record Database.DeleteResult result = CustomMetadataClient.deleteMetadata( Custom__mdt.SObjectType, new List<String>{'Developer_Name'} );
How to construct the records?
Use a Map<SObjectField,Object>
to represent each record. This is more verbose than constructing a normal SObject, but necessary because Apex complains that Custom__mdt fields are not writeable.
What does each metadata operation return?
An instance of Database.UpsertResult
is returned by upserts, and an instance of Database.DeleteResult
is returned by deletes.
We actually coerce the responses back into these native types so they make MDT operations look and feel more like normal SObject operations.
getId()
is the FullName (as opposed to the ID)getErrors()
lists details of any error messagesisSuccess()
indicates if each record succeededisCreated()
indicates new vs existing records
The intent is to provide the Metadata API response in familiar terms without introducing a new type.
Caveats
Note with all API operations, a remote site setting is needed.
HTTP callouts are not transactions and cannot be rolled back!