It’s Data about Data!
If your org was a living breathing thing, the Metadata would be its skeletal structure, but since it’s not alive (probably a good thing, if you’re a fan of science fiction, like me), let’s go with another analogy that still works.
R2D2, the lucky little droid who didn’t have a bad motivator, played some incredibly critical role in every single Star Wars movie, without ever once being the star. R2 also had some pretty important limitations but none of them ever stopped him from being an invaluable piece of the intergalactic puzzle.
Let’s say that R2D2’s blue and white Astromech chassis represents our Metadata. Let’s also assume that each Star Wars movie, in chronological order (not release order), is a different API version and you have all of those movies on a Blu-Ray disc. R2 had a number of features that carried across all the movies and, if you’re a hardcore nerd like me, you’ll also notice that many of those traits are common across all the other Astromech droids we see in the series. Rotating head, optical sensors, a pair of legs with wheels (with a third one tucked away!), and a plug-in for easy interfacing with just about any system he ran into. In the second movie (we’ll call it API 2), we found out that he also had a pair of rocket boosters that were mysteriously missing from episodes (API versions) 4, 5, 6, and (presumably) 7.
So, it sounds like someone was making updates to the little guy’s Metadata and, in the case of those boosters, maybe even making changes that remove functionality you were accustomed to using. Of course, if you really want to see R2 use those boosters again, all you have to do is go back to the version that included them. While I don’t personally recommend doing this (manually rolling back the API version or watching that particular Star Wars movie) unless you absolutely have to, you can rest assured that anytime you run that film R2’s boosters will be there. The new movie comes out in 2017 and it’s anybody’s guess whether R2 might have some new toys to play with.
Everything that’s happening now, is happening now!
To take the analogy a little bit further, let’s all agree that there are some plot holes in the series. Things that were true in one movie, let’s say “Revenge of the Sith” (API 3), may or may not continue to be true in another like “Return of the Jedi” (API 6). Yet within the context of either film, everything operates as if there were no contradiction at all. If you need Princess Leia to have memories about her mother, you should be running API 6 not API 3. For Star Wars fans, this isn’t an ideal scenario but, for folks running a Salesforce.com org it can actually be a really good thing.
See, when you save Apex Class or Trigger, it has to compile before Salesforce will actually save it for you. Once it’s saved, new classes are assigned the current API version automatically and existing ones continue to save with their original assignment, which is part of how Salesforce guarantees backward compatibility. You can think of the API version as a description of the state of the platform for that Release and if your Apex Class compiles, it’s compatible with that state and can generally be assumed to always be compatible going forward (unless of course, it’s not, but let’s not muddy the waters just yet) even when the state changes with a new release. An Apex Class compiled under API version 32 will always run in the context of API version 32, even if the current version is API 38, and even if it is called by a class compiled under API 37.
Just in case that late bit got a little confusing, let’s see if we can’t get one last Star Wars analogy out of this. Let’s pretend that I’ve got a pair of Blu-Ray players, both attached to the same monitor, and I can seamlessly switch between which player is feeding the screen at any time. I’ve decided that R2 should really be using those rocket boosters in “A New Hope” (API 4), even though we know that they appear in “Attack of the Clones” (API 2). I’ve got a sequence from API 2 queued up on one player while I’m rolling API 4. When the moment comes that R2 has to somehow manage to traverse a set of stairs, I switch the video feed over to the other player, running the clip with R2’s boosters, then quickly switch back to the original player so that it appears that R2 flew at just the right moment and no one has to watch any more of “Attack of the Clones” than they have to.
While this is absolutely a simplification and there is definitely more going on under the hood, hopefully, it’s enough for folks to get a general idea and understand that API versions are a pretty important thing of which to be aware. We’ll let the Star Wars analogy go for now and focus on Salesforce Metadata and a specific instance that recently came up.
What’s my API again?
A colleague was running into problems with AccountShare records not ending up with the correct Edit access after assigning a User to an Account Team in an Apex Class (the OWD for Accounts was Read-Only). He did precisely what any reasonable Cloud Mechanic would do, he Googled it. (No joke, this is always the first thing I do when I run into something that doesn’t make sense. You could code without Google, but why on Earth would you want to?) What he found recommended creating the AccountTeamMember record as well as the AccountShare record. This didn’t seem to be working, so he got me involved and we took a look.
The first thing I thought was, “Well, just set the AccoutAccessLevel on the AccountTeamMember to Edit when you create the record.” I didn’t see this in the code, nor in the references he had discovered through the Magic G. Sure enough, we found the field, made the update in the code, and everything worked. Before you start chalking up a point for the Cloud Mechanic, let me give you two other facts. First, I knew that field was there and editable, but only because I had used it on a project earlier in the year. Second, while the field has been available for some time, it has always been Read-Only and only recently become editable in API 37 (take a look at these two screens if you don’t believe me).
Neither of us realized that this tiny, tiny change to the Metadata had even happened and I was completely clueless that it hadn’t always been that. Both of us learned something!
The moral of the story is, while I don’t expect everyone to have the time to pour over every word and syllable in the Release Notes, if you’re doing something custom directly with the Metadata, make sure you’re at least taking a look at it directly (I’m a huge, huge superfan of Workbench for this very thing) because you never know what you might find.