0

I need to set up a daily batch job that makes an REST API call to an external service and updates contact records in salesforce. The data in the external service changes once daily. The external system stores the salesforce contact record ID which I hope to use to update records in salesforce.

My question is, the typical salesforce batch job has a "start" method where I am supposed to gather the records for processing. In this scenario, I do not know which records I will be processing as that is the point of my API call to the external service.

Is it possible to omit the start method or something similar that will still allow me to use the batch framework of salesforce?

3
  • To answer directly - no, you cannot omit the start method; this is a fundamental method you have to implement for a batchable.
    – Phil W
    Aug 24, 2020 at 6:41
  • This REST API call - is the number of contacts to update each day relatively limited or can it be arbitrarily large? Also, does the REST API call define all the values with which the various contacts are to be updated? I ask because you may hit issues caused by memory limits regardless of the processing approach.
    – Phil W
    Aug 24, 2020 at 6:43
  • It is possible to use just a class that implements the scheduleable interface that is not a batch class where I can just have the execute method? The data size will vary @PhilW and the REST API call will define all the values needed to update the contact records in salesforce. The API does provide support for pulling records changed after a certain day/time. Aug 24, 2020 at 7:07

2 Answers 2

1

The problem you face is how to handle an arbitrarily large response from the REST API. The benefit of using a batch is to limit the number of objects processed (SOQL and DML) in a single session/transaction against the server. The disadvantage is that you need to know the objects to which processing is to be applied.

IF the REST API state data is compact you could in principle pass this to the batchable constructor and hold it as instance data. This data can be stored mapping contact IDs to the updates to be applied. You can then return a trivial query locator that selects contacts based on the contact IDs that make up the map's key set (SELECT Id FROM Contact WHERE Id IN :updatesByContactId.keySet()). Each execute will then return a sub-set of the contacts, and you can quickly look up the changes to be applied from the map. Apply these changes then at the end update all these contacts.

This implies ensuring that the callout is performed from the schedulable before invoking the batch, much as @Jitender Padda has suggested.

NB: If the REST API data is small enough - not too many contacts to update - you could process it all directly after the callout response is obtained, but you run the risk of hitting limits if you cannot know the maximum number of contacts that can be returned in one execution of the callout.

5
  • The api returns records in batches of 50 maximum per page. I would need to make multiple api calls to return all the records when there are more than 50 so based on your response @PhilW it seems it would work to process it directly after the callout response is obtained? Aug 25, 2020 at 6:11
  • If the API returns only 50 Contacts to be updated then, yes, why not?
    – Phil W
    Aug 25, 2020 at 7:29
  • 50 per page, there may be 500 contacts in total, meaning I would page through 10 pages returning 50 each time. I think my question is more around would I hit limits with this approach @PhilW Aug 25, 2020 at 16:25
  • When you say 10 pages, are these to be processed together in a single transaction (one apex execution), or is each a separate transaction? Even if this is a single transaction, updating 500 contacts should generally not cause issues, but it could if there is a lot of automation attached to Contact (triggers, auto-launch flows, process builder flows etc.) and this might push you over the CPU limits. Note that CPU limits are higher for async transactions (future, queueable, batchable, schedulable).
    – Phil W
    Aug 25, 2020 at 16:40
  • See developer.salesforce.com/docs/…
    – Phil W
    Aug 25, 2020 at 16:40
1

I think you will need a scheduled job first to run it automatically everyday so you can use that to first make the callout and get all Contact Ids and then pass those to the Batch to query and run. But problem you might face is that scheduled job doesn't allow Callouts so you might want to a future method first.

So Scheduled Job -> Future Method (Callout to fetch Contact Ids) -> Batch Class

You must log in to answer this question.

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