top of page

Supercharge Salesforce with Invocable Apex Methods

  • Writer: vinay kukke
    vinay kukke
  • May 11, 2024
  • 3 min read

Developers and admins each play crucial roles, but what happens when they collaborate? Apex, Salesforce's backend programming language, is a powerful tool that allows you to customize and enhance your Salesforce org. One standout feature of Apex is the ability to create invocable methods, which can be called declaratively by tools like Process Builder, Flow Builder, or even external systems via the REST API.


In this article, we’ll explore invocable Apex methods in depth. We’ll break down how they work, when to use them, and share real-world scenarios with code examples to demonstrate their impact. By the end, you’ll know how to leverage invocable Apex methods to enhance your Salesforce environment.


Invocable Apex Methods: The Basics


So, what makes an Apex method “invocable”? Essentially, it’s a method designed to be triggered by declarative tools or external systems. To create an invocable method, simply use the @InvocableMethod annotation and follow a few guidelines:


  • The method must be static and public.

  • It must accept at least one input parameter of a supported type (primitives, collections, sObjects, etc.).

  • If the method has an output, it must return a supported type.


Here’s an example of an invocable method that accepts a list of account IDs and returns the corresponding account names:


public class AccountUtility {
  @InvocableMethod(label='Fetch Account Names')
  public static List<String> getAccountNames(List<ID> accountIds) {
        List<String> accountNames = new List<String>();
        for (Account acct : [SELECT Name FROM Account WHERE Id IN :accountIds]) {
            accountNames.add(acct.Name);
        }
        return accountNames;
    }
}

Once defined, this method can be referenced in a process or flow, like so.


AccountUtility.getAccountNames();

The true advantage is combining complex Apex logic with the flexibility of declarative tools.


Key Considerations for Invocable Methods:


  • Only one input argument is allowed (though it can be a collection).

  • They can return a single value or a list of values.

  • Governor limits apply, just like any other Apex code.

  • They cannot be used in SOQL queries, DML operations, or approval processes.


Now, let’s dive into some real-world use cases where invocable methods shine.


Use Case: Updating Related Records


A common need is to update related records when a parent record changes. For instance, when an opportunity is marked "Closed Won," we might want to automatically mark all open tasks as complete. Here's how we could achieve that:


public class OpportunityUtility {
    @InvocableMethod(label='Complete Open Tasks')
    public static void completeOpenTasks(List<Id> opportunityIds) {
        List<Task> tasksToUpdate = [SELECT Id FROM Task WHERE WhatId IN :opportunityIds AND Status NOT IN ('Completed', 'Closed')];
        for (Task task : tasksToUpdate) {
            task.Status = 'Completed';
        }
        update tasksToUpdate;
    }
}

This method takes a list of Opportunity IDs, queries related open tasks, and updates their status. A flow triggered by a change in the opportunity’s status could then invoke this method.


Use Case: Custom Approval Processing


Another useful application is in custom approval processes. While Salesforce offers standard approval processes, more complex workflows sometimes require additional logic or integration with external systems.


Let’s consider a scenario where an "Expense Report" is approved, and we need to automatically create a related "Expense Payment" and send a notification email. The invocable method could look like this:


public class ExpenseReportUtility {
    @InvocableMethod(label='Process Expense Report Approval')
    public static void processExpenseReportApproval(List<Expense_Report__c> expenseReports) {
        List<Expense_Payment__c> paymentsToCreate = new List<Expense_Payment__c>();
        List<Messaging.Email> emailsToSend = new List<Messaging.Email>();
        for (Expense_Report__c er : expenseReports) {
            if (er.Status__c == 'Approved') {
                Expense_Payment__c payment = new Expense_Payment__c();
                payment.Amount__c = er.Total_Amount__c;
                payment.Expense_Report__c = er.Id;
                paymentsToCreate.add(payment);
                Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
                email.setToAddresses(new String[] { er.Submitted_By__r.Email });
                email.setSubject('Expense Report Approved');
                email.setPlainTextBody('Your expense report for ' + er.Total_Amount__c + ' has been approved.');
                emailsToSend.add(email);
            }
        }
        insert paymentsToCreate;
        Messaging.sendEmail(emailsToSend);
    }
}

This method handles post-approval actions, making it reusable and simplifying the logic.


Best Practices for Invocable Methods


When deciding to use an invocable method, consider the following:


  • Is the logic reusable across different processes or flows?

  • Does it require complex operations like calculations or external integrations?

  • Will the logic need to be modified independently from the process or flow?


Here are some best practices:


  • Focus on a single task or responsibility.

  • Use bulk processing to avoid governor limits.

  • Write comprehensive unit tests.

  • Include error handling and clear documentation.


Conclusion


Invocable Apex methods offer a versatile way to extend and enhance Salesforce functionality. By combining declarative tools like Process Builder with the power of Apex, you can build solutions that are both easy to manage and highly scalable.


For more information on invocable methods, visit the Salesforce Developer Documentation. Happy coding!

Comments


© 2024 by Unsigned Software Solutions Pvt Ltd.

bottom of page