I have to be honest that when I first heard about Custom Metadata Types I didn’t understand all that fanatic enthusiasm about that. People writing on Twitter that is ‘Game changer’, ‘Holy Grail of Deployment’ and stuff like that. We already have Custom Settings and we’ve been using them so long, everybody is so accustomed to that – why bother?
Life has proved I was wrong 😉 That is extremely useful feature of the Salesforce platform and comes extremely handy when dealing with deployment and app configuration. If you create package for AppExchange very often you want to make it very generic and then allow clients to customize it through Custom Settings. Problem is that when you install package on the new environment you have whole structure (Custom Settings with fields) but actual values are empty. Either you have to prepare some scripts to fill in these fields or manually complete them. I don’t have to mention that is error prone and that’s really time-consuming task which should be obviously somehow automated. Similiar situation with apps that heavily rely on custom configuration records. If you have to push you app throgh all deployment stages (think Dev, UAT, Production environments) you have to also manually migrate those configuration records (because it’s data, not metadata like e.g. workflows or validation rules). And here come into the picture Custom Metadata Types.
What are Custom Metadata Types
Let’s stick to the comparison between Custom Settings and Custom Metadata Types. Custom Settings is a structure that allows you to store some data inside. However, when you migrate it between environments you just move container with fields, not actual data.
And what is Metadata? Basically it’s data describing other data. Big advantage is that you can already store some configuration and move such prepared metadata between organizations. Look:
Think about cases like:
- assigning VAT rates to different states
- assigning country codes to different countries
- days of holidays
- reward points thresholds
- API endpoint addresses
- API credentials
OK, how do I use that? First, navigate to Setup and then type Custom Metadata Type:
Click New Custom Metadata Type in the next screen. Way of creating it, is pretty similiar to creation of new custom object in SF. As of Summer 2016 you can create new custom settings only via UI, you cannot do so using APEX (you have to make calls to Metadata API if you need to update it programatically). Worth noticing are two options at the bottom of the screen:
It tells us who should see the type:
• Public (first option) – anyone can see it
• Protected (second option) – if the type is installed as part of a managed package, only Apex code in that managed package can use it
Once we created it, please note that special suffix _mdt is appended to the API name of the object.
Creating custom fields is pretty straightforward. Custom metadata type field names have a suffix of __c, like other custom fields. Worth noticing are options that are presented to us during field creation:
As documentation is pointing out:
- Upgradeable – The package developer can edit the field after release via package upgrades. Subscriber orgs can’t change the field.
- Subscriber Editable – The subscriber org can edit the field after installing the package. Package upgrades don’t override the subscriber’s changes.
- Locked After Release – No one can edit the field after the package is released.
As i have mentioned you cannot easily create metadata records in APEX. However there is no problem with fetching them, e.g.
List<Setting__mdt> settings = [SELECT VAT__c, State__c FROM Setting__mdt];
Custom Metadata Types vs. Custom Settings
It seems that List Custom Settings one day will become thing of the past. If you check comparison below you can clearly that Custom Metadata Types have all the features plus some extra. Only missing thing is the ability to create records programatically, but that’s also in the roadmap.