Presentation held by Christian Szandor Knapp and Daniel Stange at Dreamforce 2018, September 24th, in San Francisco.
Did you have a closer look at your trigger handlers recently. In many cases, platform events can encapsulate and orchestrate your business logic much cleaner than triggers and are easier to integrate with from outside of your org. Custom metadata types enable you to make your triggers and platform event handlers configurable for yourself and - caveat emptor - customizable and replaceable across namespaces. And what about this new Trigger Context Enum? Learn to route your business logic like a pro and to conduct the traffic in your org and/or packages in reliable, performant and - if you want to - configurable ways.
Apidays New York 2024 - The value of a flexible API Management solution for O...
Route your triggers like a pro #DF18
1. Route Your Triggers Like a Pro
@ch_sz_knapp
Christian Szandor Knapp
Lead Developer, appero
Daniel Stange
Technical Architect, DIA die.interaktiven
@stangomat
2. This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the
assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we
make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber
growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any
statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services.
The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new
products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in
our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with completed and any possible mergers and acquisitions, the
immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new
releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise
customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the
most recent fiscal year and in our quarterly report on Form 10-Q for the most recent fiscal quarter. These documents and others containing important disclosures are
available on the SEC Filings section of the Investor Information section of our Web site.
Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be
delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available.
Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
Statement under the Private Securities Litigation Reform Act of 1995
Forward-Looking Statement
3. Agenda
• Setting the Stage: A Trigger Tale
• Shifting Gears: Custom Metadata
• Shifting Streams: Decouple Transactions from Business Events
• Aiming High: Try the MyTriggers Framework
Route your Triggers like a Pro
4. A Trigger Tale I: Timeless Truths
Developer wisdom
• Code has to be outside of Triggers
• Use Maps and Sets instead of Lists
• One Trigger per sObject
• Use try / catch / rollback
What We All Learned Early On
Platform Wisdom
• Triggers fire on CRUD
• Triggers run synchronously
When did you last step back to wonder how to design your Trigger handling?
5. A Trigger Tale II: The Disturbance of the Force
• Both UI and Platform are more and more event driven
Lightning Experience, Platform Events
• Development paradigms focus on modularity
Salesforce DX & Developer Controlled Packages
• Platform enhancements allow for sophisticated enterprise patterns
Custom Metadata Types, Callable Interface (WI19), Force DI Library
It's 2018 and Change Happened
10. De-Coupling Cogs with Custom Metadata Types
Introducing Maximal Configurability for Transaction Control
• Overcome tight coupling of cogs by pulling
them apart
• Distribute traction by configurable conveyor
belts
• Add new functionality without ever touching
Trigger code
11. De-Coupling Cogs with Custom Metadata Types
Introducing Maximal Configurability for Transaction Control
12. Decouple & Reorder Handlers from a Business Perspective
Use ListViews to Get a Grab on Things
13. De-Coupling Cogs with Custom Metadata Types
Business Logic Is Loosely Linked to Platform Logic via Configuration
16. Extend the Reach of Your Triggers with Events
• Events are “Triggers“ to/from internal and external systems
• Events aren‘t tied to any logic or sObject
• Jump out of any context persistently - even try {} / catch {} rollback
Handling platform events is... Handling Just Another After Insert Trigger!
Therefore: myTriggers is able to manage your Triggers and Events
17. Calling Back to the User
There is only one kind of notification in LEX: asynchronous
We can create our own by leveraging
a) PushTopics / Streaming API
b) a Custom Component in the Utility bar
… that is always around in the UI
… so we can pop up a notification
… or a whole transaction log
A Toast Is a Toast Is a Toast
20. Synergies: Trigger and Events
There Is No Event without a Trigger on the Platform
Platform Event orchestration uses the
same Trigger Framework.
Note:
There’s only AfterInsert for Events.
Our ERP can now send a “low stock
level” Event and Trigger record
updates and notifications through the
same framework.
21. Tradeoffs: Trigger and Events
Event
• External subscribers or internal long-running processes
• you don‘t need immediate results
Trigger
• When you need immediate results
• End-to-end control over the transaction
• And don't forget the joys of the "Before"-context...
23. Where Can You Take It From Here?
• Download MyTriggers from https://www.github.com/appero_com/MyTriggers
Or install our package (unlocked DCP) from http://bit.ly/MyTriggersDF18
• Start modelling your Triggers business process centric instead of sObject centric
• Break down business processes into modular steps that can be invoked
• in synchronous...
• or asynchronous contexts
Instant Notification App Apex Enterprise PatternsCustom Metadata Types
24. Last Words of Caution: Data Integrity
• Deactivating Trigger / Event handlers on the fly is great fun
• Forgetting to turn them back on again, is not
• There’s a reason why Triggers are hard to get by because they safeguard your data integrity
25. Don’t Learn the Hard Way: Resources
Essential Reads
• Dan Appleman: Advanced Apex Programming
• Andrew Fawcett: Force.com Enterprise Architecture
Referenced Technologies
• Force DI: https://github.com/afawcett/force-di
• MetadataTriggerHandler by Aiden Harding:
https://bitbucket.org/aidan_harding/metadatatriggerhandler
• Streams by BigAssForce: https://bigass.secure.force.com/streams
• TriggerX by Sebastian Wagner: https://github.com/se6wagner/TriggerX
Recommended Reads and Repos
Editor's Notes
(Szandor) Good mooooorning, Dreamforce! Daniel and I are very proud to be among the very first presenters for this year's dreamforce
My name is Christian Szandor Knapp, I a Salesforce MVP from Germany and work as Lead Salesorce Developer with appero.
(Segue to Daniel)
- and I'm Daniel, Technical Architect with DIA die.interaktiven, and a Leader of the Frankfurt, Germany, User Group
Before we start to trigger your excitements with what we believe is a game changer, some forward looking statements.
Daniel
You know this, right? Forward looking statement,...
Szandor
Present the Rationale
The Agenda
and Foreshadow the Package
Daniel
Triggers are the most timeless pieces that glue our Platform together, and there are certain things we learned early on.
Szandor
Lightning Experience works on event driven design principles
Can we tell whether the green success toast in LEX comes from synchronous or asynchronous code?
Would our users care? When? Why?
Salesforce DX walks us towards Orgs that are built upon modular pieces of code
How can we stick to "One Trigger per sObject" in this new paradigm? Is it still paramount?
What if we want to add a Trigger in a new package much later on?
* Eventually, the platform has now really turned towards Enterprise patterns, and with Custom Metadata, the new Force DI library or the upcoming Callable Interface, we’re getting into serious
Daniel:
Jump a few years back
Like everyone, the first process we automated was what we call "New Customer"
Whenever an Opportnity was won, we created a contract that related to the product bundle our customer just bought
And we updated the account record.
Pretty neat, right? Does that look familiar?
Did you notice the onboarding case we opened?
And do you remember that closing the open will fire the Account Trigger because of a standard rollup?
Well, I know my Appleman and this ran rock solid, even for thousands of records.
Szandor
Without trying to understand every detail in this picture, we immediately feel:
Phew, that’s complicated.
I wish somebody had thought of every Fawcett of a Trigger before me
In a growing business and growing salesforce org we usually end up with:
Deeply interrelated insert update logic
Pushing synchronous execution to limits
Try to explain this to your new admineloper
Szandor
Triggers are state driven and strongly coupled. To understand best what that means, let's understand a trigger as a set of cogs: If a state change occurs – that is if the cog moves one step- it necessarily moves the other cogs as well or they all don’t move at all.
That’s great because it helps you maintain a consistent state of the system.
But if one cog breaks somewhere in the machine, you need to check on the whole machine and maybe turn several gears back and forth to find out what happened or to be able to repair the cog. You can’t do this in production. And you cannot simply replace the cog with one of a different size
How can we reduce blockers from the process chain?
How can we couple this more loosely so we could swap, remove, and add parts later
Daniel takes over with Segue slide
Szandor segue
So let's have a look how we can solve this problem.
Daniel
Decoupling the “cogs” is pretty easy, because you can simply pull them apart by removing the code bits that glues them together.
But now, they’re not moving any longer?
In the mechanical world, this problem has been solved more than a century ago – by the use of driver belts, conveyors.
Lets connect the cogs with conveyors. They will move now, but don’t interlock mechanically. And if we need another gear, we can just hang in another belt
How can we transfer this to programming? What’s your Idea, Szandor?
Szandor
MyTrigger now loads its configuration from Custom Metadata – ideally, from one class per step in a business process. The classes involved are sObject agnostic and determine dynamically what kind of records they’re dealing with.
Everything is laid down in custom metadata. That means: this configuration can be deployed, modified, even switched on and off, from the UI
Szandor
This is how we might de-couple our logic hitherto set in complex execution paths into a digestible view. Instead of Trigger Handlers we have a decided to build our functionality into much shorter chunks of code centred around one step of a business process.
[highlight a few steps: ] (2 CLICKS!)
If an sObject or ClassName appears twice, it’s no error: it just means this piece of code is needed at different places. This also means easy re-usability of steps.
Szandor
Well, the solution is a trigger handler – as you might have guessed already. Not one per object only , but ever only one per org. How can this ever work? Bear with me, I’ll show you in just a few seconds.
You see we handle all the contexts – insert, update, delete - in one single trigger. And we jump off with a single method call – myTriggers.run() that does not need any parameters.
So how does the trigger know what to do?
Szandor
You don’t need to adapt a ‘step or business process view’ – you can still improve your current trigger driven model with MyTriggers – for example finer level of controls over execution paths
MyTriggers offers utility methods that allow you to selectively bypass trigger events
Note line 15 here: From the AccountTrigger, we’re telling our classic Opportunity Service to not run logic in the After Insert context of the Opportunity Trigger when we create new Opps via the AccountTrigger.
Segue Daniel
That really lifted our triggers to a new level. But now one of these cogs is moving slow.
We kind of need this fellow... But we can maybe put him on his own track.
This is where platform events come really handy. They are a communication channel to internal and external subscribers listeners. Whoever listens run in its own contexts completely independent
So we can jump out of the execution context and have a fresh, separate context. And this even works in operations that are completely rolled back in case of an error.
Szandor jumps in
The most obvious use case is a robust logger.
If you want to listen to platform events – well that‘s yet another trigger in the after insert context. And that means that the patterns we just showed also apply here.
Szandor:
And the concept of asychronously running events sounds familiar for lightning Devs. The interaction in the Lightning Experience UI is event driven, actually all of LEX is event driven.
There is only one kind of notification model in LEX: asynchronous (and that's... an event!) - so your UI can listen to platform events as well and toast messages to the users.
And why would that be a reason to change your current implementation, you ask. Let’s walk you through a demo.
Daniel
Has to run the "no demo"
Segue to Szandor: Now there's a decision we have to make, right?"
Daniel Segue
Daniel
Daniel
Szandor
Szandor
As promised, you will not leave this session empty handed: You can take home the MyTriggers
Szandor
Szandor
In the beginning of my career, I was a one man code show in very fast growing business.
…
And with that, it’s a wrap.
Segue to Daniel and END
A quick reminder: You can still sign up for your seat in the Developer Keynote! – Thursday at 1pm!
Daniel
Thank you for joining us this morning – it’s amazing to see so many of you here!
There are a couple of Min left for a question or two, and we will stay around for some
Have wonderful week here at Dreamforce!