Skip to main content

Salesforce Callout using Future Method

Hi All,
Today's topic , Use of Future method in web services callout.
Consider one scenario, Whenever ,We create one Account record or Edit a Account record using UI, Populate Billing city based on Billing Zipcode . Like Below image before save,


After Press the save button,Billing city should auto populate.




We want to populate Billing city based on Billing zipcode using below API endpoint.
Postal PIN Code API
Postal PIN Code API allows developers to get details of Post Office by searching Postal PIN Code or Post Office Branch Name of India.
It has following format:

        1. Get Post Office(s) details search by Postal PIN Code
            http://postalpincode.in/api/pincode/{PINCODE}

        2.Get Post Office(s) details search by Post Office branch name
           http://postalpincode.in/api/postoffice/{POSTOFFICEBRANCHNAME}

Postal PIN Code API returns the response in JSON format. "Status" field in response is set to SUCCESS or ERROR, "Message" field will return message against the request and "PostOffice" field will return data.

Example 1 (Search by Postal PIN Code):
To get details of a PIN Code (110001), use following query

Response For Valid PIN Codes:
{"Message":"Number of Post office(s) found: 21","Status":"Success","PostOffice":[{"Name":"Baroda House","Description":"","BranchType":"Sub Post Office","DeliveryStatus":"Non-Delivery","Taluk":"New Delhi","Circle":"New Delhi","District":"Central Delhi","Division":"New Delhi Central","Region":"Delhi","State":"Delhi","Country":"India"}]}

Response For Invalid PIN Codes or Error messages:
{"Message":"No records found","Status":"Error","PostOffice":null}

------------- 
Link:- http://postalpincode.in/Api-Details

When making a callout from a method, the method waits for the external service to send back the callout response before executing subsequent lines of code. Alternatively, you can place the callout code in an asynchronous method that’s annotated with @future(callout=true) or use Queueable Apex. This way, the callout runs on a separate thread, and the execution of the calling method isn’t blocked.
When making a callout from a trigger, the callout must not block the trigger process while waiting for the response. For the trigger to be able to make a callout, the method containing the callout code must be annotated with @future(callout=true) to run in a separate thread
Now let us check the coding section,
1. Trigger on Account object.
//Why to check System.isFutute and System.isBatch
//Futute method cannot be call from another future method. After update trigger will call future method from future method , result will error "CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AccountTrigger: execution of AfterInsert caused by: System.AsyncException: Future method cannot be called from a future or batch method". 
// Update the trigger logic to leverage the System.isFuture() and System.isBatch() calls so that the future method invocation is not made if the current execution context is future or batch. Record created through such cases should be handled separately using a scheduled batch job or Replace the future method with Queueable Apex. 

trigger Pincode_Address on Account (after insert,after update) {
 if(!System.isFuture() && !System.isBatch()){
    for(Account acc:trigger.new){
        Apex_callout.callcount(acc.BillingPostalCode,acc.Id);
    }
    }

}

2. Now call the End point URL using @future callout by passing the zipcode.

public class Apex_callout {
 @future(callout=true)
 Public static void callcount(string zipcode,id ids){
     Http http=new Http();
     HttpRequest req=new HttpRequest();
     req.setEndpoint('http://postalpincode.in/api/pincode/'+zipcode);
     req.setMethod('GET');
     HttpResponse res=http.send(req);
     system.debug('--->>'+res);
     if(res.getStatus()=='OK' && res.getStatusCode()==200){
       //To deserialize the JSON body , created a class pincode 
        pincode pc=(pincode)JSON.deserialize(res.getBody(), pincode.class);
        Account accd=[select id,BillingCity from Account where id=:ids limit 1];
         system.debug('---->>>++'+accd.BillingCity);
         if(accd.BillingCity==''||accd.BillingCity==Null){
             accd.BillingCity=pc.PostOffice[0].Circle;
             update accd;
         }  
       }
     }
}

3. To deserialize the JSON ,created the below class.Which you can create using https://json2apex.herokuapp.com/ . Just you need to paste the Json string and it will convert to apex class.



public class pincode {

public String Message;
public String Status;
public List<PostOffice> PostOffice;

public class PostOffice {
public String Name;
public String Description;
public String BranchType;
public String DeliveryStatus;
public String Taluk;
public String Circle;
public String District;
public String Division;
public String Region;
public String State;
public String Country;
}

}
4. Don't forget to update the Remote Site settings  :)



Comments

  1. Find a pincode is a finest Indian pin code search engine provides information about Delhi pin code, Pin code Bangalore pin code, Pune pin code and all India post offices, pin codes, localities.

    ReplyDelete

Post a Comment

Popular posts from this blog

How to Build a Basic Salesforce REST API (With Test Class)

How to Build a Basic Salesforce REST API (With Test Class) and Test with POSTMAN Salesforce : Creating Anonymous Apex REST APIs with Force.com The Force.com REST API lets you integration with Force.com applications using standard HTTP methods. This API provides a way to expose the data you have within your Force.com application to external applications – both mobile and non-mobile. A few useful bits of information related to these REST APIs: This sample Code you how to implement a simple REST API to fetch Account in Apex class: @RestResource(urlMapping='/Account/*') global with sharing class MyRestResource { @HttpGet global static Account doGet() { RestRequest req = RestContext.request ; RestResponse res = RestContext.response ; String accountId = req.requestURI. substring ( req.requestURI. lastIndexOf ( '/' ) +1 ) ; Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = : account...

Salesforce UNABLE_TO_LOCK_ROW: unable to obtain exclusive access to this record

Unable to lock row - Record currently unavailable errors Description When a record is being updated or created, we place a lock on that record to prevent another operation from updating the record at the same time and causing inconsistencies on the data. These locks normally last for a few seconds and when the lock is released, other operations can do whatever processing they are supposed to do on the record in question. However, a given transaction can only wait a maximum of 10 seconds for a lock to be released, otherwise it will time out. Resolution What and when records get locked depends on the operation you are performing and the main record you are working on. The  Force.com Record Locking Cheatsheet   provides detailed information on this and it's highly recommended that you familiarize yourself with its contents. Common Scenarios that prevent unlocking record a. Email-To-Case When an email is processed by email-to-case, triggers on the email mes...