This is a continuation to the previous post Batch Apex, Inner Queries and Iterators.

Can we invoke REST API from Apex? If Yes, then how and if No, then why?

I want you to take a moment and think about this 👆

Am still waiting for your answer!

Okay. So the answer is YES we can invoke REST API from Apex. I don't see a reason that stops us from invoking REST API!

Now comes the next part of the question, how?

We cannot just put the code related to making a callout in the Batch and expect it to work.

Just like how we implement our class with implements Database.Batchable when we want to make it a batch class we need to implement one more interface which is Database.AllowsCallouts.

Our class need to implement the above mentioned interface, it's only then our class will be equipped to make callouts.

global class HelloWorldBatch implements 
    Database.Batchable<sObject>,Database.AllowsCallouts{
    //do something
    }

P.S - Do not forget to add the endpoint in the Remote Site Settings, else it's not going to work.

How can we handle "Read Timed Out" error in Batch Apex(when we make a callout)?

There are a couple of things you need to consider here

  1. You can set the timeout on your HttpRequest or Web Service callouts to a higher value. Something like this ..
HttpRequest req = new HttpRequest();
//set timeout to 1 minute
req.setTimeout(60000);

2.  In you still encounter this error, you can adjust the query you perform on the external system, to reduce the size of the response message.

How can we maintain the state between different batches or chunks?

By now you would have known that since we are using Batch Apex large dataset will be broken down in to multiple small chunks or batch and each batch will be executed asynchronously, meaning, one batch is completely independent when compared with the other batch.

But there might be a few scenarios where we need to maintain the state between the batches. Let me give you a scenario, let's say we are trying to log the no of batches that got executed as a part of this.

In such cases our class need to implement one more interface which is Database.Stateful.

That's it, after we implement the interface we can modify the value of the variable(or auto increment the value of the variable) and variable is going to maintain the state between batches.

global class HelloWordBatch implements Database.Batchable<sObject>, Schedulable, Database.stateful{
	public Integer i = 0;
	//start
	global Database.QueryLocator start(Database.BatchableContext BC){
	}
	
	//execute
	global void execute(Database.BatchableContext BC, List<sObject> scope){
		I += 1;

	}
	
	//finish
	global void finish(Database.BatchableContext BC){
	}
}