(Heroku and Salesforce - From Idea to App, Part 8)
This is the eighth article documenting what I’ve learned from a series of 13 Trailhead Live video sessions on Modern App Development on Salesforce and Heroku. In these articles, we’re focusing on how to combine Salesforce with Heroku to build an “eCars” app—a sales and service application for a fictitious electric car company (“Pulsar”) that allows users to customize and buy cars, service techs to view live diagnostic info from the car, and more. In case you missed my previous articles, you can find the links to them below.
Modern App Development on Salesforce and Heroku
Jumping into Heroku Development
Data Modeling in Salesforce and Heroku Data Services
Building Front-End App Experiences with Clicks, Not Code
Custom App Experiences with Lightning Web Components
Lightning Web Components, Events and Lightning Message Service
Automating Business Processes Using Salesforce Flows and APEX
Just as a quick reminder: I’ve been following this Trailhead Live video series to brush up and stay current on the latest app development trends on these platforms that are key for my career and business. I’ll be sharing each step for building the app, what I’ve learned, and my thoughts from each session. These series reviews are both for my own edification as well as for others who might benefit from this content.
The Trailhead Live sessions and schedule can be found here:
https://trailhead.salesforce.com/live
The Trailhead Live sessions I’m writing about can also be found at the links below:
https://trailhead.salesforce.com/live/videos/a2r3k000001n2Jj/modern-app-development-on-salesforce
https://www.youtube.com/playlist?list=PLgIMQe2PKPSK7myo5smEv2ZtHbnn7HyHI
Last Time…
Last time we explored ways to automate back-end processes on Salesforce using Flows and APEX and created several automations for our eCars app using Record-Triggered Flows and an APEX trigger. This time we are focusing entirely on how Heroku apps and microservices can help our Salesforce app scale for high-volume use cases.
Setting Up the App and Scratch Org via Github
The eCars app Salesforce and Heroku code are available on Github at the following URL:
https://github.com/trailheadapps/ecars
Go to the apps->ecars-services directory for the specific Heroku services code for this session. The readme section in the directory contains useful information for deploying to Heroku.
To get things set up we’ll need to deploy the Salesforce application to a Salesforce scratch org as well as the Heroku apps to the Heroku platform. If you are jumping into the middle of this series and have not yet set up your scratch org, it would be a good idea to go back to the first article in this series to review how to set up scratch orgs and your Salesforce dev hub as well as sign up for a free developer account on Heroku.
To get a high-level idea of the architecture of the app, the following slide details how Sales Cloud and the Car Order Configurator will be interacting with the Heroku app and its microservices.
For deployment, we get two different methods on how to manage this (1) Automated and (2) Manual.
To start, let’s review the steps for Automated Deployment as also listed on the readme section in the Github repo. Julian has created a script (a Node.js program that will make this process easier) to get this up and running in the Salesforce and Heroku platforms. All of the installation pre-reqs, keys, and steps to configure your operating system before we move forward with deployment can be found here.
The automated deployment instructions reminds us of a few things: You must be authenticated in DevHub using the SF CLI and Heroku CLI, and you must have access to the repository in order to clone it:
After cloning the repo and opening the project in VS Code, we can execute the eCars deployment script using the node binary + javascript file. This will show you a screen asking you various questions. It’s important that _developers read through all questions in detail _because it will tell you the applications you are going to deploy. The script checks for git, node, SF CLI, and the Heroku CLI to ensure all the prerequisites are there. The script also requires you to answer a series of questions before continuing and then the deployment will take approximately 10 minutes to complete. This might be a step where specific system configurations or pre-requisites get missed and you may get error messages. If so, you can post on the Chatter group discussion forum for this series to ask for help.
The output of the script final steps of instructions
The goal of this is to simplify the process for you as much as possible. The final items are “post-deployment steps” to perform after completing the automated deployment. For extra credit, check out the Manual Deployment for further understanding and learning (as well as a place to check out more detailed information should you run into errors during auto-deploy).
In the JavaScript file, we have SF CLI commands, Heroku CLI commands, as well as Linux commands to perform automation. This is an example of a robust use case for devs on what you can do with a node script. Julian, the developer who authored the script, used the Shelljs package (you can check out this powerful library here – note the weekly downloads!) because it provides the ability to write an automation that can run in both Windows and Unix platforms. It is an “implementation of Unix shell commands on top of the Node.js API” which you can review in more detail on the README here.
Deep Dive into the Node.js code and useful functions/scripts
Those of you familiar with Node.js will know that you can use core modules as well as extend things easily with third-party modules. In this case, the Shelljs library provides the JavaScript object (JSON) that contains all of the required content to execute the external commands. Check out the screenshots below which show examples of exporting the commands from the index.js file and requiring them in our ecarsDeploy.js file.
Exporting the functions as JSON
Requiring them in the ecarsDeploy.js file
We continue to break down the modules and the code that starts the deployment process by function.
With javascript and Node.js, it’s important to get familiar with the well-known asynchronous functions that contain a command and then a callback function that runs when the external function or callback completes. Unlike strict-typed languages like APEX, things don’t execute in one thread so we have to manage cases where the external function/callback might run into a problem and never give us the callback. Since we don’t want to block execution and end up waiting forever for the callback, the standard in dealing with asynchronous operations like this is to use the async/await pattern. This relies on something called “Promises”, which all javascript developers should be familiar with. Promises allow you to execute async operations and guarantee they will return a value back without blocking the main execution thread.
Another useful tool is the sed (“stream editor”) Linux command that allows you to replace strings in a file. Our app uses the sed command to access a template and substitute the correct URLs.
This command is extremely powerful because it gives you the ability to use the sed command to quickly modify metadata before pushing it into Salesforce.
The PDF Creation Microservice
A common request for applications like the eCars app would be to generate a PDF document from data collected in the system. In this case, we are going to create a PDF of a car configuration that can then be printed by the sales user for the customer. Creating PDFs is actually a high-cost CPU operation, relatively speaking, so we are going to leverage a Heroku microservice to offload this from Salesforce to Heroku.
Architecture and components between SF and Heroku for PDF generation process
Here’s what we will expect to happen once this is implemented. A potential customer builds a car on the eCars app and submits a request for it. This creates a lead in Salesforce. In Salesforce, on the lead record, we can then access the Web Push Notification (another Heroku microservice) telling the lead their car is ready.
Now let’s say your lead is at the dealership and building a different version of the car. In the Car Configurator, a sales user can walk through the steps of model, color, and interior and can then attach the lead in Salesforce and generate a PDF with the car’s details.
This PDF will be generated in Heroku and come over as an attachment on the files related list on the Lead record in Salesforce:
So how do we do this? First, the configuration information data gets sent from Salesforce to the Heroku microservice. Heroku is using Node.js and a few libraries/modules to achieve this—specifically, Fastify, PDFmake, and JSforce. One of the beauties of Heroku is the ability to combine all of these libraries to build powerful applications for a variety of use cases. Now some descriptions of each library:
Diving first into Fastify, we are using Piscina to help offset the load on the Heroku service as generating PDFs can be an intensive CPU operation. Piscina is a library to help manage something called the “workerThread” to generate the PDF and “downlog” the main thread of the application. This is implemented as a POST route, so we can have an APEX class in Salesforce that makes a callout to that endpoint via a POST method.
Then we have a PDFGenerator
class in the PDFMake library to be able to generate the PDF. This includes the savePDFtoLead
custom function that saves the PDF to the Salesforce lead.
Finally, jsForce is a javascript library that helps with interacting with the Salesforce REST API in javascript applications. In the jsForce code, there are functions to authenticate and create a connection to Salesforce as well as functions to send a SOQL query to Salesforce and get back and parse the results of that query.
To handle the PDF generated by the PDFMake library, we are receiving our PDF as a buffer and writing it back to Salesforce as a ContentVersion record (basically Salesforce Files) to the Lead record we retrieved in our previous query.
You can move a lot of this around and re-architect it as you see fit. This is one of the powerful things about microservices. Mohith mentions that devs overwhelmingly agree that “services should be as dumb as possible” to avoid creating any dependencies and can exist as the simplest and most atomized version of the service. This allows you to scaffold things up with multiple services and extend things more easily.
For some homework, you’ll want to check out the car-configurator LWC and explore the front end of the eCars app as well as the PDFCreateService APEX class to see how it is implemented to work with the microservice.
And don’t forget to explore the sample app gallery on Github.
Concluding Thoughts
In several of my clients’ projects, I was brought in because the internal admin or a previous developer got “stuck” trying to implement a particular requirement that was seemingly impossible to do with Salesforce because there was no declarative solution or way to do something in APEX code. Often in these cases, an external microservice solved the problem.
Once you realize that Salesforce has the capability to make web service callouts to external services, really the sky's the limit for what can be implemented when you combine Salesforce with microservices. It’s also important to remember that not only can Salesforce make callouts to external services, but external applications can make callouts to a number of Salesforce APIs to allow for bi-directional interactivity between Salesforce and third-party or homegrown applications.
Salesforce has so many APIs, it’s sometimes easy to forget what’s possible
In the next article, we’re going to do some additional work with Salesforce and Heroku microservices in a second part for this topic. Yes, there was too much good stuff to fit into one episode!
If you haven’t already joined the official Chatter group for this series, I certainly recommend you do so. This will give you the full value of the experience and also pose questions and start discussions with the group. Oftentimes, there are valuable discussions and additional references available there such as the slides from the presentation and links to other resources and references.
About me: I’m an 11x certified Salesforce professional who’s been running my own Salesforce consultancy for several years. If you’re curious about my backstory on accidentally turning into a developer and even competing on stage on a quiz show at one of the Salesforce conventions, you can read this article I wrote for the Salesforce blog a few years ago.
Top comments (0)