Continuation Chaining Asynchronous Callouts

If the order of the callouts matters, or when a callout is conditional on the response of another callout, you can chain callout requests. Chaining callouts mean that the next callout is made only after the response of the previous callout returns. You can chain up to three callouts.The following Visualforce and Apex examples show how to chain one callout to another.

public with sharing class ChainedContinuationController {
    
    // Unique label for the initial callout request
    public String requestLabel1;
    // Unique label for the chained callout request
    public String requestLabel2;
    // Result of initial callout
    public String result1 {get;set;}
    // Result of chained callout
    public String result2 {get;set;}
    // Endpoint of long-running service
    private static final String LONG_RUNNING_SERVICE_URL1 = 'https://www.zipcodeapi.com/rest/XUdRusqAL97aO28KYyMzfhZmkBLzSl7Qs853mWwzTSlxLRktAmrNTfQ2kr9bd8BE/info.json/95051/degrees';
    private static  String LONG_RUNNING_SERVICE_URL2 ='http://openweathermap.org/data/2.5/weather?q=santa%20clara&appid=b6907d289e10d714a6e88b30761fae22';
    
    // Action method
    public Object invokeInitialRequest() {
        // Create continuation with a timeout
        Continuation con = new Continuation(10);
        // Set callback method
        con.continuationMethod='processInitialResponse';
        
        // Create first callout request
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        req.setEndpoint(LONG_RUNNING_SERVICE_URL1);
        
        // Add initial callout request to continuation
        this.requestLabel1 = con.addHttpRequest(req);              
        
        // Return the continuation
        return con;  
    }
    
    // Callback method for initial request
    public Object processInitialResponse() {   
        // Get the response by using the unique label
        HttpResponse response = Continuation.getResponse(this.requestLabel1);
        // Set the result variable that is displayed on the Visualforce page
        this.result1 = response.getBody();
        
        ZipParser parser =  (ZipParser) System.JSON.deserialize(response.getBody(), ZipParser.class);
        System.debug('parser'+parser);
        
        Continuation chainedContinuation = null;
        // Chain continuation if some condition is met
        if (parser.city!=null) {
            // Create a second continuation 
            chainedContinuation = new Continuation(10);
            // Set callback method
            chainedContinuation.continuationMethod='processChainedResponse';
            
            // Create callout request
            HttpRequest req = new HttpRequest();
            req.setMethod('GET');
            
            // LONG_RUNNING_SERVICE_URL2 ='http://openweathermap.org/data/2.5/weather?q='+parser.city+',usa'+'&appid=b6907d289e10d714a6e88b30761fae22';
            req.setEndpoint(LONG_RUNNING_SERVICE_URL2);
            
            // Add callout request to continuation
            this.requestLabel2 = chainedContinuation.addHttpRequest(req); 
        }
        
        // Start another continuation 
        return chainedContinuation;  
    }    
    
    // Callback method for chained request
    public Object processChainedResponse() {   
        // Get the response for the chained request
        HttpResponse response = Continuation.getResponse(this.requestLabel2);
        // Set the result variable that is displayed on the Visualforce page
        this.result2 = response.getBody();
        System.debug('result2result2'+result2);
        // Return null to re-render the original Visualforce page
        return null;
    }
    
    
    public class ZipParser{
        public String zip_code;	//95051
        public Double lat;	//37.348656
        public Double lng;	//-121.984433
        public String city{get;set;}	//Santa Clara
        public String state{get;set;}	//CA
        public cls_timezone timezone;
        public cls_acceptable_city_names[] acceptable_city_names;
    }
    public class cls_timezone {
        public String timezone_identifier;	//America/Los_Angeles
        public String timezone_abbr;	//PST
        public Integer utc_offset_sec;	//-28800
        public String is_dst;	//F
    }
    public  class cls_acceptable_city_names {
    }
    
    
    
    
    
    
}

 

<apex:page controller="ChainedContinuationController" showChat="false" showHeader="false">
    <apex:form >
        <!-- Invokes the action method when the user clicks this button. -->
        <apex:commandButton action="{!invokeInitialRequest}" value="Start Request" reRender="panel" />  
    </apex:form>
    
    <apex:outputPanel id="panel">
        <!-- Displays the response body of the initial callout. -->   
        <apex:outputText value="{!result1}" />
        
        <br/>
        <!-- Displays the response body of the chained callout. -->
        <apex:outputText value="{!result2}" />
    </apex:outputPanel> 
    
</apex:page>