Or how to handle synchronous calls with slow backends
I spent a long time of my experience Salesforce creating integrations with other systems: from Mainframes to microservices.
One of the main painful problems with synchronous integration in Salesforce is the timing constraint — especially because Salesforce imposes, with governor limits (10 callouts taking more than 5 seconds per instance) — and as I said, I worked with plenty of integrations serving different needs for different departments (Sales, Support, Channels, so on so forth). That meant that across any of those departments, we should avoid having integrations taking more than 5 seconds. That is the requirement and sounds easy: especially if you ignore document generation systems or even complex orchestrations that tend to go beyond this threshold with minutes sometimes easily.
To address this need, Salesforce delivered Continuations in Spring’15 — I still remember when I first read the blog post in 2014 about this and the many use cases we could have. By the way, seems that their implementation relies on Jetty Continuations (you can search the archived aura repo).
I remember to then start using and recommending this approach with Visualforce. Since then, loads of things have changed (including the rise of Aura and Lightning Web Components — or simply LWC) but no option to use Continuations with those new stacks.
Now on Summer’19 they finally expanded to Aura and LWC, and that is why I’m writing.
One of the main differences from the code I wrote and the ones I found by Salesforce is the usage of Named Credentials — which in case you are not familiar with, this is one of the best tools to store Endpoints and their respective authentication parameters (I can spend 2h just explaining how that makes your life so much easier).
So, I bundled everything you need to try it on your scratch org.
LWC Imperative callout (most common)
This imports the method
Then I wrapped the call into a new function called
callContinuation that uses the imported function and then using a promise it either store the result or error in
imperativeContinuation. The button on UI calls
LWC Wire callout (new approach)
This is one is more elegant because the call is made on this case implicitly when the component is loaded.
startRequestWire is imported into a variable with the same name, then the trick is to annotate with
@wire(startRequestWire) when defining
wiredContinuation. That will inform the LWC framework to call the function when the component is loaded.
There is also another requirement on the Apex Controller: both the apex method that initiates the callout and the callback must be annotated with
cacheable=true along to
On this case, I’m checking the result stored in
wiredContinuation also, displaying either the
data in case of success or
error in case of any failure.
I hope you enjoyed as much as I did and now have a new tool in your toolbelt to manage integrations between Salesforce and other systems.
The project is available on GitHub: