Custom metadata in salesforce

Salesforce provides a comprehensive platform for managing your sales, service, and marketing automation to suit your business needs. However, handling configuration data within code was difficult and inefficient. With the introduction of custom metadata, developers are able to deploy code that can change custom functionality based on the configurations set from custom metadata records.

What is custom metadata

Custom metadata is customizable, deployable, packageable, and upgradeable application metadata. This means you can create applications that behave differently based on the data stored in custom metadata. Once read, custom metadata records are cached at the type level, improving performance for subsequent requests.

You can push these records as metadata into different Salesforce orgs as well as into managed packages.

When to use custom metadata

When you need to control system behaviors based on configured values, custom metadata may be one of the best options to consider. Moreover, if you want to avoid the hassle of managing these configurations across different environments, custom metadata becomes incredibly useful.

Custom metadata vs custom settings

Custom settings were one of the choices before custom metadata was introduced, which can be used to record configuration at the platform level, but they lacked the ability to be packaged and deployed to various environments. The following is a quick comparison between custom metadata and custom settings.

  • Custom metadata

    Custom settings

  • Can be used to store a list of records.
    Can be used to store a list or hierarchy based records.
  • Records can be deployed via the Metadata API or can be packaged and upgraded in the case of managed packages.
    Records cannot be deployed via metadata api or managed package.
  • Fields support various data types, relationships and validation rules.
    Limitted field support but no relationship lookups or validation rule support.
  • Records are available for apex test class.
    Records needs to be re-created for apex test class.

How to create a custom metadata

To create custom metadata navigate to set up -> search for custom metadata types -> click 'New custom metadata type'.

Creating a new custom metadata in salesforce

How to add record into custom metadata

To add custom metadata records:

Go to set up -> custom metadata types -> and click on your custom metadata name then click on manage and click on the new button to add new custom metadata records.

Adding new records to custom metadata in salesforce

Bulk load/import custom metadata records

To insert bulk records into custom metadata, run the following sf command from visual studio code terminal. The following command will generate the custom metadata records for the type mentioned.

Once the metadata records are generated, use the deploy option in visual studio code to deploy the records to your org.

sf cmdt generate records --csv path/to/my.csv --type-name Account_Setting

Alternatively, you can install the Custom Metadata Type Data Loader from appexchange.

Deploying custom metadata

Deploying custom metadata involves two steps. The first step is deploying the metadata file of the custom metadata, and the second step is deploying the records of the custom metadata.

As per our previous custom metadat exmple for 'Account_setting', we have a file under object for the metadata.

  • 1. Metadata file
  • The metadata file is the definition of the custom metadata object which inlcudes the custom metadata object, fields, relationships.
  • 2. Custom metadata records
  • The custom metadata records are the actual metadata records you've created or imported into the custom metadata object.
Deploting custom metadata records in salesforce

Using custom metadata in apex

Apex support built in methods to work with custom metadata records. The following are the apex methods to work on custom metadata in salesforce.

1. getAll()

Returns a map with key as developername and values as the sobject records.

Map<String,Account_Setting__mdt> mapMetadata = Account_Setting__mdt.getAll();
//Returns Demo -> Account_Setting__mdt as per our example.

2. getInstance(recordId)

Returns the custom metadata record based on the record id.

Account_Setting__mdt accountMetadata = Account_Setting__mdt.getInstance('m02J2000000Gmbg');
//Returns Account_Setting__mdt record by id.

3. getInstance(developerName)

Returns the custom metadata type record based on the developer name.

Account_Setting__mdt accountMetadata = Account_Setting__mdt.getInstance('Demo');
//Returns Account_Setting__mdt record by developer name.

Using custom metadata in apex test class

Apex test class have access to org's custom metadata by default and does not require additional set up. If your org has custom metadata already set up, the test classes will have access to it and no additional set up is required.

Query custom metadata from developer console / VS code

The custom metadata records can be queried directly from the developer console or from visual studio code. The custom metadata api name needs to be used inorder to query the records. Please see a sample query below.

1. Query from developer console

Query custom metadata from developer console

2. Query from vs code

Query custom metadata from vs code

Using custom metadata in validation rules

Custom metadata types can be used in validation rules. The syntax to use custom metadata records in validation rules is as follows:

$CustomMetadata.CustomMetadataTypeAPIName.RecordAPIName.FieldAPIName

The following is a sample validation rule that prevents users from entering annual revenue greater than $10,000 for the type 'Customer - Direct':

ISPICKVAL(Type,'Customer - Direct') && 
AnnualRevenue > $CustomMetadata.Account_Setting__mdt.Demo.Max_Annual_Revenue__c

In the above example, we've used custom metadata named 'Account_Setting__mdt' with a record named 'Demo' to determine the maximum limit for a direct customer. The annual revenue limit is configurable and stored in the 'Max_Annual_Revenue__c' field on the custom metadata.