Newer Version Available
Chaining Asynchronous Callouts
The following Visualforce and Apex examples show how to chain one callout to another. The Visualforce page is shown first. The Visualforce page contains a button that invokes the action method invokeInitialRequest in the controller. The Visualforce process is suspended each time a continuation is returned. The Visualforce process resumes after each response is returned and renders each response in the outputPanel component.
1<apex:page controller="ChainedContinuationController" showChat="false" showHeader="false">
2 <apex:form >
3 <!-- Invokes the action method when the user clicks this button. -->
4 <apex:commandButton action="{!invokeInitialRequest}" value="Start Request" reRender="panel"/>
5 </apex:form>
6
7 <apex:outputPanel id="panel">
8 <!-- Displays the response body of the initial callout. -->
9 <apex:outputText value="{!result1}" />
10
11 <br/>
12 <!-- Displays the response body of the chained callout. -->
13 <apex:outputText value="{!result2}" />
14 </apex:outputPanel>
15
16</apex:page>This example show the controller class for the Visualforce page. The invokeInitialRequest method creates the first continuation. The callback method (processInitialResponse) processes the response of the first callout. If this response meets a certain condition, the method chains another callout by returning a second continuation. After the response of the chained continuation is returned, the second callback method (processChainedResponse) is invoked and processes the second response.
1public with sharing class ChainedContinuationController {
2
3 // Unique label for the initial callout request
4 public String requestLabel1;
5 // Unique label for the chained callout request
6 public String requestLabel2;
7 // Result of initial callout
8 public String result1 {get;set;}
9 // Result of chained callout
10 public String result2 {get;set;}
11 // Endpoint of long-running service
12 private static final String LONG_RUNNING_SERVICE_URL1 =
13 '<Insert your first service URL>';
14 private static final String LONG_RUNNING_SERVICE_URL2 =
15 '<Insert your second service URL>';
16
17 // Action method
18 public Object invokeInitialRequest() {
19 // Create continuation with a timeout
20 Continuation con = new Continuation(60);
21 // Set callback method
22 con.continuationMethod='processInitialResponse';
23
24 // Create first callout request
25 HttpRequest req = new HttpRequest();
26 req.setMethod('GET');
27 req.setEndpoint(LONG_RUNNING_SERVICE_URL1);
28
29 // Add initial callout request to continuation
30 this.requestLabel1 = con.addHttpRequest(req);
31
32 // Return the continuation
33 return con;
34 }
35
36 // Callback method for initial request
37 public Object processInitialResponse() {
38 // Get the response by using the unique label
39 HttpResponse response = Continuation.getResponse(this.requestLabel1);
40 // Set the result variable that is displayed on the Visualforce page
41 this.result1 = response.getBody();
42
43 Continuation chainedContinuation = null;
44 // Chain continuation if some condition is met
45 if (response.getBody().toLowerCase().contains('expired')) {
46 // Create a second continuation
47 chainedContinuation = new Continuation(60);
48 // Set callback method
49 chainedContinuation.continuationMethod='processChainedResponse';
50
51 // Create callout request
52 HttpRequest req = new HttpRequest();
53 req.setMethod('GET');
54 req.setEndpoint(LONG_RUNNING_SERVICE_URL2);
55
56 // Add callout request to continuation
57 this.requestLabel2 = chainedContinuation.addHttpRequest(req);
58 }
59
60 // Start another continuation
61 return chainedContinuation;
62 }
63
64 // Callback method for chained request
65 public Object processChainedResponse() {
66 // Get the response for the chained request
67 HttpResponse response = Continuation.getResponse(this.requestLabel2);
68 // Set the result variable that is displayed on the Visualforce page
69 this.result2 = response.getBody();
70
71 // Return null to re-render the original Visualforce page
72 return null;
73 }
74}