Last week I introduced custom metadata types, an app configuration engine that will be generally available in the Summer ’15 release. This week I discuss how and when to use custom metadata types, and how we plan to further enhance their capabilities.
Custom metadata types are like list custom settings, but with records that are metadata rather than data. This means that enterprises can deploy these records from a sandbox, something that can’t be done with data records. ISVs can package these records and customers can install them. This makes custom metadata types an ideal tool for building app configurations. (See last week’s post for details.)
Custom metadata types vs. custom settings
For the most part, custom metadata types can do everything that list custom settings do, only better. Here is a high-level comparison of the similarities and differences:
You will notice that custom metadata types don’t yet beat list custom settings in every respect. So who should use custom metadata types and how should you use them?
App configurations for enterprises
Most customers considering list custom settings or custom objects for app configurations should use custom metadata types. The primary limitation of custom metadata types for enterprises is the lack of a user interface.
In return for the one-time inconvenience of setting up a UI, you can use custom metadata types to migrate app configuration records from development through various testing environments and into production without manual intervention or custom-built tools. This saves time and money, reduces the opportunity for errors, and most importantly, reduces compliance headaches associated with manual interventions into your application lifecycle management.
For most organizations, this benefit is well worth the the cost of creating a UI. And to help minimize that cost we have provided some great tools, which I discuss toward the end of this post.
App configurations for ISVs
Like customers, partners considering unprotected list custom settings or custom objects as configuration objects will usually be better off with custom metadata types. The ability to package and deploy these configurations without writing any install scripts saves months or years of development effort. And since many of you create your own UI, the lack of out of the box UI won’t be an obstacle.
Where to package your records
As you design your app, carefully consider editability of your configurations.
Developer-editable records: Put metadata records you want to control in your application’s managed package, along with the custom metadata types themselves. These records are visible but not editable by your customer or your app’s code. Only you can change them through a package upgrade. (Labels and descriptions are exceptions; these can be updated by the customer.)
Subscriber-editable records: Put metadata records you want edited by either your code or your customer in a separate unmanaged package. Your customer (subscriber) and your code can edit these records but package upgrades will not touch them (since unmanaged packages can’t be upgraded), protecting the customizations your customer makes.
Using a combination of managed and unmanaged packages gives you per-record control over editability, something you can’t get with custom settings. With custom settings, you can hide an entire object to prevent customers from customizing it, which also prevents them from even seeing it. Or you can leave it exposed, in which case your customer can edit any of its records, potentially breaking your app.
Market-specific extensions: If you want to provide configurations that differ by market – for different countries or industries, for example – create a series of extensions of your main package, one for each market. These can be either unmanaged or managed, depending on the editability you want to provide. You can then upgrade managed extension packages independently of one another.
Protected custom metadata types
Records in protected (hidden) custom metadata types are developer editable only. That may sound obvious, but this is an important distinction from protected custom settings.
Your code can edit and add records to protected custom settings, but it cannot do so in protected custom metadata types. This is because Apex can create, update and delete data but cannot do so natively for metadata. (You can help bump up the priority of adding this capability by voting for “Ability to update Metadata from Apex” in IdeaExchange.) The only way to create or update records in protected types is by upgrading your managed package.
This supports some important use cases. However, in some cases you may want your customer or your code to add or modify some records while others are hidden. The best way to achieve this now is by using two tables that do essentially the same thing, protect one of them and leave the other visible.
Naturally, all of the following comes with a Safe Harbor disclaimer.
In the coming months, our immediate priority is to remove key limitations that custom metadata types have compared to list custom settings. Specifically, we will:
- add a native user interface
- give developers the ability to protect individual records rather than locking down entire types
- give developers the ability to delegate control of customizing (updating) individual fields to customers
(The latter two apply to managed packages only.)
Protecting individual records will allow you to put hidden and visible records in the same metadata type rather than creating two similar types as described above. (Note that once records are released as unprotected, you will not be able to protect (hide) them in the future.)
The ability for developers to delegate control over update on each field will allow you to put all your records in your managed package. You won’t need to use a combination of managed and unmanaged packages to manage editability. And to simplify your app, you’ll be able to move any records that were previously in an unmanaged package to the managed package.
After we add these features, the next exciting enhancement on our roadmap is the ability to add relationships from your custom metadata to other things in your app, such as other custom metadata, custom or standard objects and fields, and static recourses.
Because custom settings do not support relationship fields, some developers use custom objects to store app configurations instead of (or in addition to) list custom settings. When metadata relationships are released, custom metadata types will be able to replace the custom objects your app uses as configuration objects.
Until then you will need to create metadata relationships the same way you create relationships for custom settings: by using an API name in a text field. Though not ideal, this is common practice for custom settings.
We have created several resources to help you develop your app configurations in custom metadata types.
“Custom Metadata Types” chatter group at success.salesforce.com
In the Chatter group you will find documentation, videos and sample application. There is also a community of developers available there to help.
Out-of-the-box configurable UI
Salesforce developer Jean-Baptiste Pringuey has built a handy configurable UI for basic key-value pair custom metadata. It’s available on GitHub. (This project was inspired by the Salesforce Foundation’s Cumulus project and leverages the Apex Wrapper for the Salesforce Metadata API built by Salesforce MVP Andrew Fawcett.)
Salesforce developer and inventor of custom metadata types, Avrom Roy-Faderman, and several engineers on the team have built a sample application, which is available in the above-mentioned Chatter group. Along with the documentation, this app gives you a tour of the many capabilities of custom metadata types. And you can reuse code from this sample app to help you build your apps.
Build more manageable app configurations, and do it faster
Custom metadata types let you create your own metadata types in Salesforce for the first time ever. You are no longer limited to customizing types that Salesforce provides. Custom metadata types are a great app configuration engine and make your application lifecycle management and compliance easier, faster and more robust.
Even with the limitations of this initial release, anytime you consider adding list custom settings to your app, take a serious look at using custom metadata types as an alternative. I think you will find it a superior solution for most situations.
Please join the “Custom Metadata Types” Chatter group, avail yourself of the resources there, and build your next app with the Salesforce1 Platform’s new app configuration engine. Then let us know what you have built and how you have used custom metadata types. And of course, let us know what features you most want to see in the future!
Correction: The original version of this article incorrectly stated, “there is no upgrade path from a protected custom metadata type to a type where individual records are protected.” It has been corrected to say that once released, unprotected records cannot subsequently be protected.