This post provides a high-level overview of the Winter ’16 enhancements to the Custom Metadata Types platform capability.
Custom Metadata Types – The App Configuration Engine for Force.com
There are in my view two distinct ways to consider Custom Metadata Types (CMT); firstly as analogous to Custom Settings and secondly as an architecturally significant paradigm shift in regard to platform extensibility. In the former case CMT can be viewed as a straightforward, almost like-for-like replacement to List Custom Settings – with the added benefit that records can be deployed as metadata. There are of course considerable differences between the two, however conceptually this view is simplistic and approachable. In respect to the latter case, prior to CMT platform extensibility for Force.com could be viewed as a vertical model where new instances of pre-defined metadata types are created to deliver custom interactions. Custom Metadata Types enable a horizontal extensibility model where new type definitions can be introduced and instances created as metadata. The platform is no longer constrained to the pre-defined set of metadata types, developers have freedom to extend the model and deploy both the types and instances freely across environments. This horizontal extensibility model enables a host of new use cases such as bespoke development frameworks that abstract or extend the Force.com platform, an idea variously described as Platform-on-a-Platform or Custom Platform.
Custom Metadata Types were introduced as a beta release in Spring ’15, with the GA release in Summer ’15. The enhancements added to Winter ’16 appear to represent another milestone on the journey toward an increasingly capable platform extensibility model where custom types can be related to standard types, perhaps to override or extend platform behaviour. This is definitely a key area of the Force.com platform to pay attention to over subsequent releases.
Note, the native user interface for Custom Metadata Type administration shown in the following screenshots is a new Winter ’16 feature, previously Metadata API calls were required to define types and manage associated records.
As the screenshot below shows, Custom Metadata Types support Custom Fields and Page Layouts, all very consistent with the Custom Object and Custom Setting equivalents (although not layouts in the Custom Setting case). At this point it’s worth considering the fact that all standard metadata types are comprised of a collection of attributes, for example an ApexClass has Name, Body attributes in the same way a CustomField has Name, Label, DisplayType attributes. This is how Force.com platform metadata is structured. The difference between a CMT and a Custom Object or Setting isn’t the definition it’s the type of data stored; with a CMT we’re recording metadata. Taking a somewhat obscure example, we could invent a new proprietary platform language called Opex (;-)), define a CMT called OpexClass with a Body attribute etc., populate it with metadata records that represent a System namespace and ship some actual ApexClass instances to translate and run the Opex code. I’ll concede this isn’t a practical example, however the point I hope should be clear.
The protected component attribute applies to Managed Packages; meaning visibility of the CMT in a Subscriber org.
When defining a new CustomField for a Custom Metadata Type, there are limitations to the field types that can be specified and as-per Custom Settings there are no picklist or relationship fields (as yet anyway).
Field Manageability is a new concept in Winter ’16 to understand, again in relation to Managed Packages. In short this setting provides field-level editability control, selectable values being:
Locked after release : Field value is locked after deployment (includes the developer org).
Subscriber editable : As the name suggests; deployed (developer) updates will not override subscriber field value changes.
Upgradable : Locked in the subscriber org, developer can edit and deploy upgrades.
A Metadata Record is really where Custom Metadata Types head off on their own path; a Metadata Record as the name implies represents an instance of the metadata type as a record that can be manipulated by the Metadata API, deployed via Change Set and packaged. The significance of which is obvious but incredibly powerful. It becomes possible, for example, to track Metadata Records using Source Code Control tools and to deploy metadata plus configuration via a single deployment transaction. No more, 2 stage deployments or clumsy post-install data loading.
As can be seen in the preceding screenshot it is possible to define a Protected Component setting at the Metadata Record level. This enables the type to be public but records to be selectively hidden in the subscriber org – a very flexible capability.
As mentioned in the introduction the Custom Metadata Type platform feature is still emerging, in my view at least, the most interesting aspects are potentially yet to be revealed, however there are definitely some key benefits to highlight with the Winter ’16 release.
For Enterprise : Manual steps within an otherwise automated Application Lifecycle Management process can cause compliance issues and release management inefficiency. Custom Metadata Types enable application configurations to be deployed as part of a seamless, one-step deployment process thereby removing manual friction. Configuration management tools can also track and version control the application definition and its configuration state.
For Partners : A long time issue for ISVs has been the deployment of application configuration data as part of the managed package installation process. Post install scripts provide one option, but creating data via Apex script doesn’t scale well or deliver the required fine-grained control over subscriber org configurability and upgradeability. Custom Metadata Types address both issues.
The screenshot below shows both a Custom Metadata Type and Metadata Records added to a Managed Package definition.
Note, the benefits stated above are those practical benefits of the capability in relation to its generic capability, the actual benefit for many developers will be the flex
Audit trail : Changes to both Custom Metadata Types and Metadata Record are visible via the Setup Audit Trail, this is new to the Winter ’16 release.
Metadata Record Access : Metadata Records can be accessed via SOQL query only, there is no direct Apex support. Note the __mdt suffix.
Widget__mdt widgets =
[select QualifiedApiName, Height__c, Width__c from Widget__mdt];
Metadata Record Modification : Custom Metadata Types do not support DML operations via Apex, the Metadata API must be used. For use cases where configuration data needs to be created via code, CMT may not be an effective approach.
Relationship Fields : At some stage (Spring ’16 perhaps) in the future evolution of Custom Metadata Types I would expect support for relationships to be provided. This I believe is where the feature will really take-off.
Apex Testing : Currently Metadata Records are visible in Apex unit tests (without SeeAllData=true), it’s likely that simulated test data will be supported in a future release to enable testing under different configurations.
Permissions : The permissions model for Custom Metadata Types is limited, the Metadata Records are either visible or not at the org-level. A finer-grained permission model, perhaps just at the record level would be an obvious progression.