+ Start a Discussion
vignesh balasubramanian 14vignesh balasubramanian 14 

How to make Http callouts in batch class

Hi Everyone,

Could anyone explain me that how to make Http callouts in batch class with example.

Note:Need to call the batch class from apex trigger
Best Answer chosen by vignesh balasubramanian 14
Varun SinghVarun Singh
Hi try this,
 
global class BatchSync implements Database.Batchable<sObject>,   Database.AllowsCallouts {

 public String query = 'Select ID, Name from Account';
 global Database.QueryLocator start(Database.BatchableContext BC) {
    return Database.getQueryLocator(query);
 }

     global void execute(Database.BatchableContext BC, List<Account> records) {         
        String endpoint;        

        for ( integer i = 0; i< records.size(); i++ ){
         try {                  
          HttpRequest req = new HttpRequest();
          HttpResponse res = new HttpResponse();
          Http http = new Http();
          // Set values to Params

          endpoint = 'Your endpoint';

          req.setHeader('Authorization', header);
          req.setHeader('Content-Type', 'application/json');
          req.setEndpoint(endpoint);
          req.setMethod('POST');
          req.setBody('Information you wanna send');
          req.setCompressed(true); // This is imp according to SF, but please check if
                                 // the webservice accepts the info. Mine did not :P
                                 // Had to set it to false

          if (!Test.isRunningTest()) {      
            res = http.send(req);
            String sJson = res.getBody();
            System.debug('Str:' + res.getBody());
          }             
          // now do what u want to with response.               
          }
          catch (Exception e) {         
            System.debug('Error:' + e.getMessage() + 'LN:' + e.getLineNumber() );           
          }
       }
    }   

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

BatchSync BS = new BatchSync();
Database.executeBatch(BS,10); // you can also do less than 10

You can also take  help from these   link

1-https://developer.salesforce.com/forums/?id=906F0000000kK6VIAU
2-http://www.forcedisturbances.com/2012/03/caching-data-from-googles-geocoding.html

I Hope you will choose my answer as best answer

All Answers

v varaprasadv varaprasad
Hi Vignesh

To use HTTP Callouts in batch class we need to use Database.allowcallouts in interface.
More info check below links : 

http://www.cloudforce4u.com/2013/11/call-batch-apex-from-trigger.html
https://salesforce.stackexchange.com/questions/19444/batch-apex-with-webservice-callout (http://www.cloudforce4u.com/2013/11/call-batch-apex-from-trigger.html)


Hope this helps.
please let me know if you need any further information.

Thanks
Varaprasad

 
vignesh balasubramanian 14vignesh balasubramanian 14
Hi Parasad,
I tried but it shows " System.AsyncException: Database.executeBatch cannot be called from a batch start, batch execute, or future method " error.
Kindly give me solution to fix it.

Thanks,
Vignesh.b
v varaprasadv varaprasad
Hi Vignesh,

you are calling callouts batch class in Trigger right?

Please use @future(callout = true) to execute method and checkonce.


Thanks
Varaprasad
Varun SinghVarun Singh
hI Vignesh try  this,

Step 1: Create Apex Class
First step is to create an apex class. After you login, click on Setup > Develop > Apex Classes > New. 
Step 2: Write future method
Write future method that calls external service.
 
public class AccountUpdater {

  //Future annotation to mark the method as async.
  @Future(callout=true)
  public static void updateAccount(String id, String name) {

    //construct an HTTP request
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://cheenath.com/tutorial/sfdc/sample1/data.txt');
    req.setMethod('GET');

    //send the request
    Http http = new Http();
    HttpResponse res = http.send(req);

    //check the response
    if (res.getStatusCode() == 200) {

      //update account
      Account acc = new Account(Id=id);
      acc.Description = res.getBody();
      update acc;
    } else {
      System.debug('Callout failed: ' + res);
    } 
  }
}

Step 3: Add external server to Remote Sites
Click Setup > Security Controls > Remote Site Settings > New Add external site name and endpoint URL
Site:cheenath endpoint url:http://cheenath.com/


Step 4: Create APEX trigger
Click Setup > Customize > Accounts > Triggers > New
And create the following trigger:
trigger descriptionUpdater on Account (after insert) {

  System.debug('Making future call to update account');
  for (Account acc : Trigger.New) {
    //Call future method to update account
    //with data from external server.
    //This is a async calls, it returns right away, after
    //enqueuing the request.

    AccountUpdater.updateAccount(acc.Id, acc.Name);
  }

}

 
vignesh balasubramanian 14vignesh balasubramanian 14
Hi Varun,
Yes, it works well, but not for bulk records thats why I'm asking you the way to achieve this using batch class.
 
Varun SinghVarun Singh
Hi try this,
 
global class BatchSync implements Database.Batchable<sObject>,   Database.AllowsCallouts {

 public String query = 'Select ID, Name from Account';
 global Database.QueryLocator start(Database.BatchableContext BC) {
    return Database.getQueryLocator(query);
 }

     global void execute(Database.BatchableContext BC, List<Account> records) {         
        String endpoint;        

        for ( integer i = 0; i< records.size(); i++ ){
         try {                  
          HttpRequest req = new HttpRequest();
          HttpResponse res = new HttpResponse();
          Http http = new Http();
          // Set values to Params

          endpoint = 'Your endpoint';

          req.setHeader('Authorization', header);
          req.setHeader('Content-Type', 'application/json');
          req.setEndpoint(endpoint);
          req.setMethod('POST');
          req.setBody('Information you wanna send');
          req.setCompressed(true); // This is imp according to SF, but please check if
                                 // the webservice accepts the info. Mine did not :P
                                 // Had to set it to false

          if (!Test.isRunningTest()) {      
            res = http.send(req);
            String sJson = res.getBody();
            System.debug('Str:' + res.getBody());
          }             
          // now do what u want to with response.               
          }
          catch (Exception e) {         
            System.debug('Error:' + e.getMessage() + 'LN:' + e.getLineNumber() );           
          }
       }
    }   

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

BatchSync BS = new BatchSync();
Database.executeBatch(BS,10); // you can also do less than 10

You can also take  help from these   link

1-https://developer.salesforce.com/forums/?id=906F0000000kK6VIAU
2-http://www.forcedisturbances.com/2012/03/caching-data-from-googles-geocoding.html

I Hope you will choose my answer as best answer
This was selected as the best answer
Amit Chaudhary 8Amit Chaudhary 8
Remember to mention Allowcallouts=true on batch context then you can do callout u=in batch job
 
global class  BatchName implements Database.Batchable<sObject>,Database.AllowsCallouts {

}

Please check below post for sample code
1) https://salesforce.stackexchange.com/questions/19444/batch-apex-with-webservice-callout

 
Ragula SivakumarRagula Sivakumar

Hi All,

I need some inputs how to integrate salsforce with gOogle adwors API . I have specific CRM  campaign information id which is matching with awords campaign and needs to update the data.
How to achieve this.