Call Apex Invocable Method From Salesforce Flow – Part 2

by Sudipta Deb | Jan 29, 2025 | Apex, flow, Invocable, Salesforce | 0 comments

Sudipta Deb

Sudipta Deb

Founder of Technical Potpourri, Co-Founder of Shrey Tech, Enterprise Cloud Architect

In Salesforce, bulkification of code is essential due to the platform's multi-tenant architecture and the associated governor limits. Salesforce operates on a multi-tenant architecture, meaning that multiple customers (organizations) share the same underlying hardware and infrastructure. This shared environment necessitates strict resource management to ensure that no single customer monopolizes resources and impacts the performance of others. To enforce fair resource usage, Salesforce imposes governor limits on Apex code, which is the platform's programming language. 

Without bulkification, Apex code would process records one at a time. This becomes inefficient and can easily lead to exceeding governor limits when dealing with large datasets. Bulkification is the practice of writing Apex code to handle multiple records in a single transaction, minimizing the number of SOQL queries and DML statements. 

I have already published a blog post/video covering the basic use case of handling a single record type. If you haven't checked it out, I will highly suggest you first go through that first as it creates the foundation. I will provide the link below. But in this post/video, I will share a more complex use case where I will create my own input type and pass that to the Apex method. In return, the Apex method will return me a custom output type.

The form you have selected does not exist.

Watch The Video Or Read The Article (Or Do Both smile)

Let's Understand The UseCase

The Use Case I will be implementing today is - "From Screen Flow, I will be passing a list of cases and a list of contacts to the Apex method. The Apex method will return the flow two lists. The first list will contain the case description of all selected cases. The second list will contain the contact names of all selected contacts".

This is a complex use case. I will be creating my own custom input and output types to implement the above scenario.

Implementation Approach

To implement the above use case, I will be writing an invocable apex class which I will call from record-trigerred Salesforce Flow. Again very straightforward. So without any further delay, let's start implementing the use case.

Let's Write The Apex Class

As you can see in the below Apex class, I have created custom InputVariable and OutputVariable. Both of them are inner classes. InputVariable contains Case List and Contact List. Both of them are annotated with @InvocableVariable. The reason for this annotation is that from Salesforce, I will be passing selected cases and selected contacts to the invocable apex method. The input parameter for the apex invocable method will be a list of InputVariables. The invocable apex method will return a list of OutputVariables, which contains two lists. One will contain case's description, whereas the other will contain the selected contact's name.

And finally the InvocableMethod fetchCaseAndContactDetails dealing with my custom InputVariables and OutputVariables.

public with sharing class FetchCaseContactInformation { 
 @InvocableMethod(label='Fetch Case And Contact Details' description='Returns the list of strings holding Case Descriptions and Contact Names' )
 public static List<OutputVariables> fetchCaseAndContactDetails(List<InputVariables> inputs) {
 System.Debug('--++-- SD: Inside fetchCaseAndAccountDetails'); 
 List<OutputVariables> outputs = new List<OutputVariables>();
 OutputVariables output = new OutputVariables();
 List<String> allCaseDescriptions = new List<String>();
 List<String> allContacts = new List<String>();  for(Case singleCase : inputs.get(0).allCases){
 allCaseDescriptions.add(singleCase.description);
 }
 for(Contact singleContact : inputs.get(0).allContacts){
 allContacts.add(singleContact.Name);
 }
 output.allCaseDescriptions = allCaseDescriptions;
 output.allContactNames = allContacts;
 outputs.add(output);
 return outputs;
 }  public class InputVariables {
 @InvocableVariable
 public List<Case> allCases;
 @InvocableVariable
 public List<Contact> allContacts;
 }
 public class OutputVariables {
 @InvocableVariable
 public List<String> allCaseDescriptions;
 @InvocableVariable
 public List<String> allContactNames;
 }
}

Let's Build The Flow

This is going to be a screen flow. The first two elements of the flow are to fetch cases and accounts from the organization with the Get Records element.

With that in the next screen element, I will be displaying fetched cases and accounts inside a datatable as shown below in the screenshot.

In the next step, I will be passing the selected cases and contacts to my invocable method. The configuration is displayed below in the screenshot.

As you can see in the above screenshot, I am passing Selected Cases and Selected Contacts into the allCases and allContacts input variables. Both of these variables are annotated with the InvocableVariable annotation.

Now in the next screen, I am displaying the return values (from the Apex invocable method) inside a new screen with a Display Text element. Configuration is shown below.

Reference Documents

Final Thoughts

I hope this two-part series of blog posts and YouTube videos will provide you with all the details that you need to work with Invocable Methods and call them from Salesforce Flow.

Disclaimer

This article is not endorsed by Salesforce, Google, or any other company in any way. I shared my knowledge on this topic in this blog post. Please always refer to Official Documentation for the latest information.

0 Comments

Leave a Reply

Written by Sudipta Deb

Enterprise Cloud Architect, Content Creator, 20x Salesforce Certified, 1x Google Cloud Certified, 2x Copado Certified

Related Posts

Salesforce Cancels the “Permissions in Profiles” Retirement: What It Means for Admins and Architects

Salesforce Cancels the “Permissions in Profiles” Retirement: What It Means for Admins and Architects

For the last few years, Salesforce administrators, architects, and security teams have been preparing for a major platform change: the retirement of permissions managed directly through Profiles. Salesforce had previously announced plans to move organizations toward a Permission Set–led security model, with enforcement expected to begin around the Spring ’26 timeframe.

read more...
New Apex Method | Extracting Picklist Values Based on Record Type Inside Apex

New Apex Method | Extracting Picklist Values Based on Record Type Inside Apex

For years, Salesforce developers have faced a common challenge: programmatically retrieving picklist values that are specific to a certain Record Type directly within Apex. The “solutions” often involved either complex SOQL queries against metadata, relying on the UI API (with its associated callout limits and serialization overhead), or maintaining clunky custom metadata/settings.

Good news, Technical Potpourri readers! The Salesforce Spring ’26 release is bringing a game-changer that will significantly simplify your Apex code and improve performance: native Apex methods to filter picklist values by Record Type!

read more...

0 Comments

Leave a Reply