How to use custom iterator in apex batch class

Apex batch classes are used to process large volume of records that can hit governor limits if processed synchronously. Batch classes are used to split these large set of records into small chunks and execute as separate transactions. Batch class can work on up to 50M sObject records using QueryLocator or upto 50k records using Iterator. Using list of sObjects is a common pattern and you can find a sample batch class template here. There are two ways of using iterator approach. it can either be a or a There are cases where using a Iterator is more meaningful. You can find some use cases below,

  1. Use a custom iterator defined using CustomIterable interface
  2. You can just use standard apex collections like list as iterator. Because they are implementing Iterable interface behind the scenes

Use cases

  • If your batch class needs to operate on data obtained from two unrelated objects, you can create a custom iterable class and return combined data from both objects as a list of iterable from start method
  • Say you have an API that returns ~5k product Ids and then you need to hit another API for each of these products to get more details about each product. You can return a list of product Ids from start method to achieve this.


Explanation

Apex batch classes can return an iterator to process large volume of data that are not directly queried from database/sobjects. These iterators can be classes implementing Iterable interface or standard apex data strucutres like list. In above example we are getting a list of animals and details of individual animal from an API hosted in Heroku. It is used by Salesforce for trailhead modules. Here "baseUrl/animals" gives a list of animals and "baseUrl/animals/animalId" gives details of a single animal.

Suppose the API to get list of animals gives back 1000 animal IDs. Then we cannot get details of all animals individually using single transaction. This is because currently governor limit on number of callouts in one transaction is 100. So we need to split it into multiple transactions. Best way to do this is to use apex batch. Here we use start method to make an API call to get list of all animals. Then we will process the result and finally start method will return a list of all animal Ids to execute method. Then because it is a batch, Salesforce will call execute method multiple times with a subset of total animal list each time using the batch size we specify while starting the batch. This will help us to stay within governor limits if we use correct batch size (Something below 100 in our case so that we can stay within 100 callouts per transaction limit).


How to use

  • Make sure that you are adding https://th-apex-http-callout.herokuapp.com/ in remote site settings to allow callouts to this URL.
  • Create an apex class with name "IteratorExampleBatch" and copy paste the code from above
  • Execute the batch using "Developer Console" => "Execute Anonymous" option. You can use Database.executeBatch(new IteratorExampleBatch(), 10); to execute batch with a batch size of 10

3 comments: