The describeLayout API call
currently returns an enormous, monolithic blob of critical metadata about an object, the key pieces of which are:
The problem is that describeLayout returns all of this data at once
- which makes it completely unusable in orgs with very complex metadata. For example, I was recently working in an org for a large Salesorce customer whose Case object had 14 Record Types, 150 Picklist fields, and various Layouts. The Layouts metadata was not too large, about 200KB, but the recordTypeMappings totaled up to a whopping 6MB - yes, MB - when transferred over the wire.
Why is this problematic?
Our app, Skuid, is a custom user interface development tool for Salesforce. For numerous reasons we have rolled an entirely custom runtime, using no standard Visualforce components. Therefore when we render Picklist fields in our pages, we have to do all of our own processing of Picklist Dependency information and check which Picklist values are valid for the selected Record Type. This information is ONLY available via the API, via the following traversal of the corresponding calls:
Picklist Dependency information:
traverse fields to find the corresponding field
validFor -- bytes
process the validFor bytes
Picklist values for a Record Type
traverse recordTypeMappings looking for the specific Record Type
traverse picklistValues looking for the desired Picklist
grab the picklist values
So... what are we asking for?
*** More granular access, either via the API or in Apex, to particular pieces of the describeLayout and describeSObject metadata ***
Let me give examples for improvements to each:
In the customer org above, the recordTypeMappings object for one of those 14 Record Types only takes up about 300KB going across the wire --- we can probably live with that. But we can't JUST get this recordTypeMappings, we have to get ALL of them. But what if we had a call such as:
describeRecordType(sobjectName,recordTypeDeveloperName || recordTypeId)
which would return just the results of describeLayout('Case').recordTypeMappings[recordTypeIndex] --- that is, a particular recordType's metadata, complete with it's associated Layout, picklistValues, etc.
Going a step further, perhaps we could have something like
describePicklistsForRecordType(objectName,recordTypeDeveloperName || recordTypeId,arrayOfPicklistFieldNames)
which would return just the metadata for a desired set of Picklists (e.g. the Picklists we want to render on our customer user interface) on particular Record Types, e.g.
This method would prevent us from having to get ALL metadata for ALL fields on an object when we only want just a few fields! For instance, imagine an org with 500 fields on an SObject (which NEVER ever happens... [sarcasm, it happens A LOT]). Doing a describeSObject returns the metadata for ALL fields on this object, all 500 of them, all picklist values, all properties which we may or not need...
Going a step further, what if we could request just particular metadata properties on the object?
That would even further reduce the bloat!
IMPROVEMENTS TO APEX METADATA THAT WOULD HELP
In Apex, metadata can be retrieved with much more granularity than it can via the API, which is VERY helpful. This is possible because in Apex you get handed Tokens, rather than full Describes, and you can choose whether or not to do a full Describe on an SObject or Field if needed.
However, as noted before, and as documented in this idea (which has been rather unhelpfully merged into another idea), you cannot get at describeLayout metadata, including Record Type picklist values or Picklist Dependency info, from Apex.
All that would need to be added to Apex to eliminate the need for some of the above API methods are:
- add picklistsForRecordType property paralleling API property
- add validFor property paralleling API property (ideally implemented without using the byte type!)