Salesforce DX was one of the hot topics at TrailheaDX this year. For those not familiar with it, Salesforce DX is the new “developer experience” Salesforce has been building up for the past couple of years.
It introduces tools and capabilities familiar to developers on other platforms such as source-driven development, version control, modular packaging, headless deployments, and so on.
Having taken some initial steps into the world of SFDX this year, a large chunk of the sessions I attended were related to it as I was keen to pick up anything I could use to help ease my transition to the new platform. One of the better sessions I attended was a presentation by John Daniel entitled “Architecting Unlocked Packages in Your Salesforce Org”. You can watch a video of the presentation here.
John is the Lead Platform Architect for the law firm Morgan & Morgan and his talk was mainly about the strategies his team used to execute their move to Salesforce DX. At the client I’m currently working for, we’ve limited our adoption of SFDX to small self-contained projects because frankly, the idea of converting all of the existing codebase is intimidating. Having someone like John share his experience provides a wealth of useful information and tips if we do eventually go down that path.
Here are some of the things in the presentation that stood out for me:
Possible ways of breaking up the codebase into modules
One of the key concepts of DX is the use of modular packages as opposed to having a monolithic codebase for the whole org. John and his team used the following approach to identify potential candidates for modules:
- Custom Apps – the custom apps in an org usually group a set of related objects and custom code, so they provide a good starting point for coming up with a list of possible modules
- AppExchange Customisations – when an org has an AppExchange installed, it’s likely to have custom code and config related to this. Each installed package can have its own module of related customisations.
- Unmanaged open source packages – there are a number of open source libraries and frameworks (e.g. apex-commons, financial force lib) that you can install on an org to help reduce development effort. Each of these can be in their own module
- Common functions – Basic features that are referred to throughout the multiple modules identified above can be consolidated into a core or base module.
Rename metadata to help identify which package it belongs to
When breaking up your codebase into smaller packages, you must ensure that your metadata is not duplicated on multiple packages, as this could result in unexpected behaviour. For example, if a custom field is included in two packages by mistake and their definitions aren’t exactly the same, then each subsequent deployment of a package is going to attempt to overwrite the field’s definition in another package.
John approached this by having his team implement a naming convention on the metadata before moving them to the actual DX package. All custom metadata had to be prefixed with the name of the package that it was supposed to go to. After this was completed, it made the job of moving the metadata to the DX packages easier since you could see where a piece of metadata belonged just by looking at the name.
Personally, I’m not 100% convinced of following this approach, just because I know that it’s not straightforward to do a massive revamp of API names on a live org. John did mention that it took his team 1 year to refactor the whole org to comply with this naming convention, so it’s fair bit of work. But, if you have the resources and time available, I can see the benefits of doing this to make your code more organised and readable.
Using dependency injection to decouple packages
Some of the challenges they faced were how to keep dependent packages decoupled, and the solution they came up with was a form of dependency injection through the smart use of Salesforce configuration.
One of the examples provided was that they had a base Selector class in their Core package which handled retrieving records from sObjects such as the Account object. This Selector class would be aware of all the Account fields included in the Core package, so that these fields would be included in the generated SOQL query when Account records need to be retrieved.
However, let’s say there’s a dependent package (called Foo) that introduces a custom field on the Account object (let’s call it Foo_ASICNumber__c). How would the Selector class in the Core package be made aware of the Account custom field Foo_ASICNumber__c in the Foo package without having to hardcode it?
They ended up using a combination of Custom Metadata and FieldSets. In short, if a package had any custom fields that it wanted included when the Core Selector class ran a query, they had to create a Custom Metadata record that pointed to a FieldSet that contained all of the custom fields in the package that needed to be included in the query. The Core Selector class was then refactored to look for all of these FieldSets to generate the fields included in the SOQL query at run time. If in the future, a decision is made to remove the dependent package from the org, this will not require any changes to the Core Selector class, since none of the fields in the removed package are referred to explicitly.
I’ve tried to keep things concise, but the presentation goes into more detail and also provides another example of dependency injection for handling Platform Events. The key takeaway from this is that it’s worth putting in some effort to think of similar patterns to keep your packages as decoupled from each other as possible.
Watch the video
I’ve glossed over a lot of things so I highly recommend watching the full session I’ve linked above. I think it’s worth investing some time to see it if you’re considering migrating your org to Salesforce DX packages in the near future. Making the move still seems like a daunting task, but it’s good to see what other people like John have done to help form your own plan.
I have to say that it’s great that Salesforce is finally focusing on the developer side of the platform. Also, if there’s anything you want to discuss or if you want to share your ideas on SFDX, feel free to get in touch with me through Slack or email.