There was a lot of excitement at this year's TrailheaDX around the rapidly maturing tools Salesforce is building to support source-first development and package-based deployment. CapTech's delegation included a cumulative century of enterprise Java development experience, so we were in the middle of the excitement. New tools, new toys! Source-first gives us a way to do meaningful source control. Packaging 2 lets us bundle things up in chunks that look like libraries.
Well, sort of.
For starters, how do you get from here (an ocean of Salesforce soup) to there (set of well-structured, source-controlled unlocked packages with a clean, unidirectional dependency graph)?
And, why exactly is it that we want to get there. Beyond the usual litany of 'ilities, that border on must-haves when we use Salesforce in a regulated industry, it comes down to productivity.
How can I quickly spin up a new parallel development thread? How can I manage common functionality without copy/paste reuse? How can I be sure that my automated tests always start with an environment in a known state? How can I be sure that what I tested is what gets deployed to production. But, there I go, with the 'ilities.
Back to the "how". We saw two distinct approaches to the DX journey in presentations at TrailheaDX. I'll call the first one "Building Blocks" and the second "Container Ships". More on the lame metaphors as we go.
John Daniel did an awesome job of laying out the building block approach in his TrailheaDX session. The idea is to map out a set of common library packages and feature packages to refactor your org into. By adding some dependency-injection mechanisms to things like triggers and selectors, along with custom metadata types to manage the injections, these common libraries can become rather powerful.
At the end of the journey, we'll have something like a collection of extensible Legos, each with well-defined responsibilities and dependencies. Being the Java architects that we are, we at CapTech gravitated to this model early, given the easy analogies to pushing and deploying binaries to/from a repository like Artifactory.
But then, there's this ocean of soup that characterizes many, if not most, existing orgs. Is there a way to cut directly to the productivity part without refactoring and restacking the current org? That's a daunting prospect, and might make the DX journey a hard sell in some places.
The DX Product folks, in their AMA Session at the Packaging 2 beta launch suggested another approach. Rather than packaging the world, just package the features under active development. In other words (strained metaphor alert!) rather than building a new feature package on an all-encompassing stack of packaged building blocks, founded solidly on terra firma, float the new feature package, like a container ship, on the soup ocean.
CapTech is prototyping both routes to DX nirvana, working with our own enterprise Salesforce org. One of the things we're working out is how to easily (and repeatably) spin up lean, but properly shaped, scratch orgs. With the building block approach it's obvious - follow the dependency graph. However, when the dependency graph points at soup (the ships approach), we need some creativity - the challenge being that if I need to push all the soup to achieve a usable scratch org, it's not going to be very lean.
Among our clients, we see arguments in favor of both approaches. It's becoming clear, though, that a successful packaging strategy will have some common threads, regardless of which path:
- There will be "libraries". Connections to external systems are an obvious example so far for us. I'll be shocked if we don't uncover a few others.
- Dependency injection patterns and custom metadata will be central to making those libraries truly reusable. And, based on our first couple of "container ship" exercises, DI will provide the necessary scaffolding to plug feature packages into triggers, selectors and utility classes.
- Not sure we've seen the optimal packaging approach for layouts yet. Maybe they stay in the soup? For now at least.
Hmmm… so if we start down the "ships in the soup" path, and keep carving out libraries, don't we eventually end up with building blocks?