This is part of a blog series written by the Helix Engineering staff. To follow along with the team as they publish, keep tabs on the Helix Engineering blog category.
There is a lot of technology behind the Helix Platform that delivers a friendly, secure consumer experience atop robust DNA sequencing and science-based genome analysis. And this technology is built with a rigorous engineering approach. You can’t go far down engineering row before hearing “separation of concerns, DRY, or refactor” amongst the developers.
But this blog post is about Salesforce.com, a platform reviled by users on StackOverflow as a place where engineers go to die. How could this possibly be part of the Helix software landscape?
Salesforce.com is more than a tool for salespeople
For those not in the know, Salesforce.com is a series of customizable applications built on top of a multi-tenant platform-as-a-service (PAAS) architecture. The most well-known applications are Sales Cloud, Service Cloud, and Marketing Cloud; Helix uses all three. One can customize these applications using point-and-click configuration tools.
In addition, you can write entirely custom applications on top of the PAAS, and Helix has done this as well.
When the business requirements exceed the capabilities of the point-and-click tools, Salesforce.com provides a rich procedural application development toolset including”Apex” (akin to Java) and a query language called “SOQL” (analogous to SQL). These tools are especially adapted to exploit the features provided by the Salesforce platform (e.g., security, scalability, provisioning-free) as well as to adhere to the platform’s rules of the road (e.g., don’t hog all the resources of a multi-tenant cloud).
Coding in Salesforce.com
When the need arises to add Apex and SOQL to what is provided out-of-the-box from Salesforce.com, you actually have to be pretty clever as the developer. This is because Salesforce.com requires that every application be coded to process batches in order to enforce multi-tenant good neighbor rules. Salesforce will always deliver a batch of objects to your class’s methods. The batch might be of size 1 (a user interface interaction) or up to size 200 (API calls). If you need to do queries, you can’t loop through the batch of objects and issue a query 1×1—you need to query with a collection of keys and get back a collection of records. If you need to do DML, you can’t loop through your objects and CRUD 1×1, you need to CRUD in batches. Failure to do this means you will violate one of Salesforce.com’s governors—number of queries per transaction, number of DML statements per transaction, or CPU time per transaction.
The shorthand term for all this is called “bulkification.”
Yeah, yeah. Every Salesforce.com developer knows this drill
True, and so do the engineers at Helix. Yet in many organizations, Salesforce.com developers merely code up scripts of Apex / SOQL, in what I like to call a “given a stimulus, there is a script but no architecture” style of development.
But we go a step further. Everything done in the Helix Salesforce.com customizations adheres to the Force.com Enterprise Architecture patterns that in turn are based on Martin Fowler’s enterprise application architecture patterns.
This means that the code is organized into four main interacting patterns:
• Domain Layer: Code that is related to the data and behavior of the database object. For example, the class Orders provides methods about the Order database object. Note the plural nature of the class name—Orders—because everything in Salesforce must be bulkified.
• Selector layer: Code that is related to querying objects, especially in a DRY manner. Using the Order database object again, there is an OrdersSelector class that has methods such as selectByOrderId, selectByProductCode, and selectWithOpenCasesByDate. The methods accept a collection of filters and return a collection of database objects.
• Service layer: Code that provides DRY operations to multiple clients (API, user interface, workflow, etc.). These service methods are typically business verbs such as cancel, refund, and replaceKit. Service layer classes are typically (but not always) associated with database objects, so one could have an OrdersService class. Note again the plural nature of the class name, as its methods have to always be coded to accept batches of work.
• Unit of Work layer: The unit of work layer ties together the in-memory objects that must be committed together in a specific sequence, for example: Account before Order before OrderItem.
Open Source is our friend
The four layers above—domain, service, selector, and unit of work—are thoughtfully provided as an open source GitHub library created by FinancialForce. Helix exploits this repo to enforce a consistent discipline across every line of Apex we write. Gone are the days when the Salesforce.com developer has to think about what classes to define, what their functional boundary should be, and how to provide reusable common logic. Once we adopted the Force.com Enterprise Architecture patterns, the code base became utterly predictable—it did not matter whether one was looking at application logic about Orders, Contacts, or (support) Cases.
Logic tied to managing the database objects is in the relevant Orders.cls, Contacts.cls, or Cases.cls domain class. All of the queries could be found in OrdersSelector.cls, ContactsSelector.cls, or CasesSelector.cls. And business application logic would be found within methods inside of OrdersService.cls, ContactsService.cls, and CasesService.cls. Maintenance becomes easier when one doesn’t have to divine the developer’s design process because everything follows a pattern.
As the app store for consumer genomics products, Helix deals in serious consumer transaction volumes. Every part of our software platform, including Salesforce.com, has to support these volumes while at the same time be readily adaptable to new business requirements. This means rigorous architecture and adherence to patterns placing Helix at the forefront of Salesforce.com best practices.
Eric Kintzer is Helix’s Salesforce.com architect and can be found contributing to the community on Salesforce Stack Exchange under the handle cropredy.