A technical best practice in the Salesforce domain is to employ Apex code predominantly as an enabler for the declarative platform capabilities. This light-touch approach is simple in concept; the minimum amount of Apex code necessary is introduced to enable non-technical build features to solution the functional requirement. In the majority case this works very well and provides a strong maintainability story. In more complex scenarios complete technical solution options can be warranted and are perfectly acceptable, but one should always preclude the Apex-as-glue approach first.
In practice this model can be challenging to implement. The solution design process must be driven by individuals who are both expert in the current-release declarative capabilities of the platform and have the skill and experience to deconstruct a requirement into a structured solution design composed of declarative and technical components. Typically functional experts revert to technical solution options as a last-resort and don’t always think in terms of blended solutions. Salesforce technical resources don’t usually have a deep understanding or practical experience of the functional capabilities of the platform – some do, most don’t consider this a development concern or don’t have the opportunity to build skills in this area.
The recent introduction of the (Lightning) Process Builder with its ability to invoke Apex Actions (via the InvocableMethod annotation) provides a powerful shared language between functional and technical perspectives, enabling a clear decomposition of functional and technical solution components. To elaborate on this, process automation solutions can be implemented (i.e. Processes) that are comprised of declarative functionality but also with delegation to Apex code where gaps exist. In other words a clear exemplar of the model described previously. Adding parameterised Apex Actions in this context enables declarative configuration of the technical component and removes the black-box issues related to Apex Trigger components etc.
The screenshot below shows an Apex Action invocation within the Process Builder design environment.
In consideration to the concept of Processes (or indeed Flows – the technology that underpins Process Builder) invoking Apex Actions, a new development paradigm becomes possible, one that avoids black box, inflexible Apex Triggers and places control and configuration in the hands of non-technical resources (business analyst, administrator, app builder etc.).
From the development perspective Apex Actions should be coded as reusable, encapsulated components with flexible configuration (via parameters) and simply dropped into Processes as required. Note, Actions are also invocable directly from the REST API – a further point of potential for this approach. This component-based architecture should work well for all parties. The question of when to write an Apex Trigger or an Apex Action will be influenced primarily by factors such as whether the logic applies to all record modifications or is selective and whether bulk operations must be supported at default batch sizes – at the time of writing there are governor limit considerations with Process Builder that should not apply to correctly written bulk-safe Apex Triggers.