

Apex Metadata API for Dynamic Salesforce Customizations
Salesforce is a highly customizable platform, but sometimes declarative tools like clicks and configuration aren’t enough. That’s where the Apex Metadata API comes in. This blog will explore how you can use the Apex Metadata API to dynamically create, update, and manage Salesforce metadata programmatically. Whether you’re building a custom setup wizard, automating deployments, or creating dynamic applications, the Metadata API is a game-changer. Join us to Unlocking the Power of Apex Metadata API for Dynamic Salesforce Customizations.
What is the Apex Metadata API?
The Metadata API is a Salesforce API that allows you to interact with metadata (e.g., custom objects, fields, layouts, and more) programmatically. While the Metadata API is typically used in tools like Salesforce DX or Change Sets, you can also use it in Apex to perform metadata operations at runtime.
Why Use the Apex Metadata API?
- Dynamic Customizations: Create or modify metadata on the fly based on user input or business logic.
- Automated Setup: Build custom setup wizards or onboarding tools that configure Salesforce orgs dynamically.
- Advanced Deployment Strategies: Automate complex deployment processes without relying on Change Sets or Salesforce DX.
- Custom Admin Tools: Build custom admin tools for managing metadata in your org.
Creating a Custom Object Using Salesforce Metadata API in Apex
Here’s the Apex code that creates a custom object, including a custom text field:
public static void createCustomObjectMethod(){
// Step 1: Initialize the MetadataPort to interact with the Metadata API
MetadataService.MetadataPort metadataservice = new MetadataService.MetadataPort();
// Step 2: Set the session header with the session ID to authenticate the API call
metadataservice.SessionHeader = new MetadataService.SessionHeader_element();
metadataservice.SessionHeader.sessionId = UserInfo.getSessionId();
// Step 3: Create a list of custom objects
List<MetadataService.CustomObject> customObjectList = new List<MetadataService.CustomObject>();
// Step 4: Define the custom object properties
MetadataService.CustomObject customobject = new MetadataService.CustomObject();
customobject.fullName = 'CustomObject__c'; // API name for the custom object
customobject.label = 'Custom Object'; // Label shown in the UI
customobject.pluralLabel = 'Custom Objects'; // Plural form of the label
customobject.deploymentStatus = 'Deployed'; // Deployment status for immediate use
customobject.sharingModel = 'ReadWrite'; // Sharing settings
// Step 5: Create the name field for the custom object
customobject.nameField = new MetadataService.CustomField();
customobject.nameField.type_x = 'Text'; // The type of the Name field
customobject.nameField.label = 'status'; // The label of the Name field
// Step 6: Add the custom object to the list
customObjectList.add(customobject);
// Step 7: Call createMetadata to create the custom object in Salesforce
metadataservice.createMetadata(customObjectList);
}
Breaking Down the Code
1. Initialize the Metadata API Client
- Make sure the MetadataService class is available in your Salesforce org.
- This class is available on the https://github.com/certinia/apex-mdapi/blob/master/apex-mdapi/src/classes/MetadataService.cls
Copy the MetadataService class code into your Org.
MetadataService.MetadataPort metadataservice = new MetadataService.MetadataPort();
The MetadataPort object is used to send API requests to Salesforce’s Metadata API. It’s a connection to the service that will allow you to create or modify Salesforce metadata.
2. Authenticate the API Request
metadataservice.SessionHeader = new MetadataService.SessionHeader_element();
metadataservice.SessionHeader.sessionId = UserInfo.getSessionId();
Authentication is a crucial step in any API interaction. We use the session ID (UserInfo.getSessionId()) of the current logged-in user to authenticate the request. This ensures that the request is made under the correct user’s session, with the appropriate permissions.
3. Create the Custom Object
MetadataService.CustomObject customobject = new MetadataService.CustomObject();
customobject.fullName = 'CustomObject__c';
customobject.label = 'Custom Object';
customobject.pluralLabel = 'Custom Objects';
Here, we define the custom object by setting some of its essential properties:
- fullName: The API Name for the custom object. In Salesforce, custom object API names must end with __c.
- label: The user-friendly name for the custom object, visible in the UI.
- pluralLabel: The plural form of the object label. Salesforce uses this for UI elements when multiple records are shown.
4. Create the Name Field
customobject.nameField = new MetadataService.CustomField();
customobject.nameField.type_x = 'Text';
customobject.nameField.label = 'status';
Each custom object in Salesforce requires a Name Field. In this example, we define the name field to be of type Text with a label of “status”. This field will serve as the primary identifier for records of this custom object.
5. Additional Properties for Custom Object
customobject.deploymentStatus = 'Deployed';
customobject.sharingModel = 'ReadWrite';
- deploymentStatus: Set to Deployed, meaning the object will be available immediately after creation.
- sharingModel: Defines the sharing rules. In this case, ReadWrite grants full read and write access to the custom object.
6. Add the Custom Object to the List
customObjectList.add(customobject);
Since the createMetadata method expects a list of custom objects, we add our custom object to the list.
7. Make the API Call
metadataservice.createMetadata(customObjectList);
Finally, the createMetadata method is invoked to send the metadata request to Salesforce. If successful, this will create the custom object in the Salesforce organization.
8. Test the Code
Once the coding part is done, I’m going to call the createCustomObjectMethod() from the anonymous window and see what happens.
We can see that the custom object has been created in the Object Manager. Now, I will reveal the details of the object.
Now, let’s check which fields were created according to our code.
By looking at the screenshot above, we can see that the Created By, Currency, Last Modified By, Owner, and Status fields were created. The Status field is the custom field we defined in our code, while the rest are standard fields.
You might wonder why the Currency field was created. The reason is that when multi-currency is enabled in your Salesforce organization, a standard currency field, named CurrencyIsoCode, is automatically added to all custom objects, including those created after multi-currency is enabled.
Challenges
- Governor Limits: Metadata API calls count against Salesforce governor limits, so use them judiciously.
- Error Handling: Metadata API operations can fail due to validation rules or other issues. Implement robust error handling.
- Performance: Metadata operations can be slow, so avoid using them in performance-critical scenarios.
Final Thoughts
By using this approach, you can automate the creation of custom objects in Salesforce without the need for manual configuration via the UI. This is especially useful in deployment processes, bulk object creation, or when you’re developing integrations that need to dynamically create custom objects.
However, note that this method involves working with Salesforce’s Metadata API, so you must ensure that you have the correct permissions and the Metadata API WSDL is properly configured in your org.
This code is a powerful tool for Salesforce developers looking to automate their metadata management and streamline the customization process. Hope you like our Unlocking the Power of Apex Metadata API for Dynamic Salesforce Customizations post.