0

I have to callout to an external API whenever a contact record has a certain field updated. The external API will only accept one record at a time, but of course I want to bulkify my code in the event that someone updates multiple contacts in Salesforce in a single transaction. What is the best way to generate separate requests to this API for each contact record that is updated? Right now I am thinking of the following basic framework, but I imagine there could be better ways.

I realize only so many callouts can be made in a single transaction, but I will only be dealing with 2 or 3 records at most.

Many thanks

    public static void MakeSeparateRequests(List<Contact> Cons){

        for(Contact C : Cons){
            CreateMachine(C.ID);    
        } 
    } 


    @future(callout=true)
    public static void CreateMachine(ID ContactID){         

        Contact C = [SELECT Name, Title, Email, Phone, Account.Name, Account.NumberOfEmployees                      
                     FROM Contact WHERE ID = :ContactID LIMIT 1];                                                       

        Http http = new Http();
        HttpRequest request = new HttpRequest();
        etc...  

1 Answer 1

1

You can have up to 100 callouts in a transaction, but the total number of asynchronous calls per day is relatively limited, and this design can cause a bottleneck. Much better if you just split them into groups of 100 and go from there:

Id[] values = new Id[0];
for(Contact record: Trigger.new) {
  values.add(record.Id);
  if(values.size() == 100) {
    CalloutUtils.doApiCall(values);
    values.clear();
  }
}
if(!values.isEmpty()) {
  CalloutUtils.doApiCall(values);
}

...

@future(callout=true)
public static void doApiCall(Id[] recordIds) {
  for(Contact record: [SELECT Name, Title, ... FROM Contact WHERE Id = :recordIds]) {
    HttpRequest req = new HttpRequest();
    ...

Doing it this way gives maximum performance while minimizing resource usage. Unless you run in to a problem that requires smaller batches, this is probably the simplest way to go.

You could also use Queueable, which would be my preference, but that requires a bit more setup.

2
  • Thanks, but wouldn't this create the same number of callouts as my code? Or was the goal just to reduce the number of times that a future method is invoked?
    – number41
    Commented May 19, 2020 at 23:02
  • @number41 It's the same number of callouts, but fewer future methods means less delay in delivery, and this will facilitate the rare times you may need to bulk upload records.
    – sfdcfox
    Commented May 19, 2020 at 23:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .