1

I have to call a webservice from an external system each time a new record is created on Salesforce. The external webservice accepts a single record/object instance per callout.

If I do an after-insert bulk trigger, how will I do the callouts per record? Is doing callouts in a for loop advisable?

If many records are created at the same time, will I hit the callout limits? I see only 100 callouts allowed per transaction.

Any other suggestion on this? Continuation? Queueable?

Thank you.

1
  • 3
    I like the Appleman advanced apex async pattern for this - you write all your callout requests to an async_request__c object and these get processed serially via chained queueables with fallback to future/schedulable. If the callout fails, you have a built-in way to replay. see his book - chapter 7
    – cropredy
    Jun 21, 2021 at 23:37

1 Answer 1

4

Queueable is the go-to way to do this today. You can make up to 100 callouts, then chain until you're done.

public class MyQueueable implements Database.AllowsCallouts, Queueable {
  public MyQueueable(Set<Id> recordIds) {
    this.recordIds = recordIds;
  }
  Set<Id> recordIds;
  public void execute(QueueableContext context) {
    Map<Id, sObject> records = new Map<id, sObject>([
      SELECT Fields FROM myObject__c WHERE Id = :recordIds
    ]);
    while(Limits.getCallouts() < Limits.getLimitCallouts() && recordIds.size() > 0) {
      doCalloutWith(records.get(recordids.remove(0));
    }
    if(recordIds.size() > 0) {
      System.enqueueJob(this); // Go again!
    }
  }
}

To call this:

System.enqueueJob(new MyQueueable(Trigger.newMap.keySet()));

Note that this code is future-proof; if the limits change, this code will automatically adapt to those changes.

Note also that this is a basic design, you should add error handling and retry capabilities, if necessary.

3
  • Thank you. What if the external system decides to accept a list of record instead of one single instance? Do I still opt for Queueable? Or a simple bulk trigger + @future method for callouts will be enough in terms of limits etc.?
    – S..
    Jun 22, 2021 at 5:48
  • 1
    @S.. Future methods can work if you can get the remote end to accept lists, though I'd still recommend a Queueable, because you can use the a transaction finalizer to deal with governor limits, etc. It also depends on how much data you need to send; you can only send up to 12 MB of data per transaction, so you might need to split across multiple transactions anyways.
    – sfdcfox
    Jun 22, 2021 at 12:25
  • thank you so much for the details. It's not much data, only have to send some basic text fields. I wanted to know the good way of implementing it. Going for bulk trigger with Queueable class. Thanks again for your help.
    – S..
    Jun 22, 2021 at 13:24

You must log in to answer this question.

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