Recently I wrote about “Architecture Enterprise Patterns (AEP) and Salesforce DX” and how I believe they are going to dramatically change the landscape for Salesforce developers everywhere. Today I wanted to briefly outline my progress with this reality. As part of the Salesforce DX Pilot this year, I got a first hand look at what the future holds when it comes to managing your Salesforce orgs. In addition to that, this year, as we expand to a global footprint, I’ve made it my personal mission to prepare my company for enterprise level development. Thankfully with the help of contributors like Martin Fowler and Andrew Fawcett, I believe I’m off to a great start.
Prerequisites
I will make this guide as simple to follow along as possible, but it should be noted that in order to fully grasp the benefits of this package and its practices you should at least familiarize yourself with the following
- [book] Patterns of Enterprise Application Architecture (PEAA) by Martin Fowler (also a majority of the concepts can be found and researched directly on his site as well)
- [book] Force.com Enterprise Patterns by Andrew Fawcett
- [code] Apex Commons by Andrew Fawcett (FinancialForce)
- [code] ApexMocks by Andrew Fawcett (FinancialForce)
- [tutorial] Apex Enterprise Patterns: Service Layer by Andrew Fawcett
- [tutorial] Apex Enterprise Patterns: Domain & Selector Layers by Andrew Fawcett
Also, for the purposes of this tutorial I will assume that you are already using DX or familiar with it and simply guide your through my steps for an ideal packaging of AEP within the DX structure.
NOTE: I will continue to update this article as more of my perspective on DX and the AEP evolve.
Getting Started
You should already have the SFDX CLI installed and setup, as well authorized your Hub Org.
1. Create a DX workspace
Traditional Salesforce workspaces might include .config
and .deploy
meta folders as well as the src
directory that houses /classes
, /triggers
, /etc
. but a DX workspace is likely to follow the following structure.
<project root> / <package name> / <module name> / <your source in whatever directory structure you want>
Which could look something like this:
MyProject/main/default/classes
MyProject/main/test/classes
MyProject/main/test/classes
Now as DX becomes official this should become more clear, but either way the aim is to allow for more flexibility to decouple your APEX and meta data based on projects, packages, and modules. All that to say that we are going to setup a DX workspace just for our AEP project so that it can be managed in its own repository. To begin, run this from the directory you wish to store your workspace:
sfdx force:workspace:create -n apex-enterprise-patterns
This will create a /apex-enterprise-patterns
directory with the default /force-app
folder already setup. Once that’s created be sure to change directories into your new workspace:
cd apex-enterprise-patterns
2. Clone AEP packages to your workspace
We are going to now clone what I will refer to as the traditional or metadata api (mdapi) versions of the ApexMocks and ApexCommons (aka fflib) to our workspace (I’ve chosen to maintain this within the workspace so that I can more easily track future contributions to these public projects). We will begin with ApexMocks
since it is a dependency of ApexCommons
:
git clone [email protected]:financialforcedev/fflib-apex-mocks.git Packages/fflib-apex-mocks
Followed by:
git clone [email protected]:financialforcedev/fflib-apex-common.git Packages/fflib-apex-common
*NOTE: I deployed these to a /Packages
directory so that I can more clearly indicate its purpose in the workspace
3. Convert MDAPI to Source
Next we need to convert the traditional mdapi
structure to the new DX
structure.
sfdx force:mdapi:convert -r Packages/fflib-apex-mocks/src -d force-app/apex-mocks
and
sfdx force:mdapi:convert -r Packages/fflib-apex-common/fflib/src -d force-app/apex-commons
*NOTE: Unfortunately at the time of this writing this conversion will create the following structure to include /main
but in the future it may be possible to remove this unnecessary folder.
(Optional) As a preference I’m going to remove the /main
directory and move the files respectively with the following:
mv force-app/main/default
Conclusion
In the future I may update this post with more details but rather than delay publishing my current progress I’m going to conclude my findings here for the moment. This should demonstrate some of the key differences between working with traditional mdapi
and the new DX
layout. With that said, keep in mind that only components within the DX
model can be deployed through the force:push
command. In addition, mastering the abilities of this new command interface does not have to be a daunting task of your development team, rather the aim should be to use these new abilities to script automated deployments and interactions.
Hopefully this brief example can still add some benefit to your adoption of Salesforce DX. If there is anything specific that you would like to see addressed still feel free to comment below and I will look to update the article accordingly in time. Thanks for reading!