Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have an APEX REST POST method that is being called from an external system 'A'.

Processing this POST I need to callout to another external system 'B' and based on its response continue with my application logic, eventually returning the result to system 'A'.

The problem is that I'm getting an Error: "System.CalloutException: Callout loop not allowed"

is there any way to get around this ?

share|improve this question
1  
Very interesting design, not sure what the business reason is but generally, in these cases, we do a Callout from System A directly to System B and if there is any data that you want to get from Salesforce you can do by APEX REST GET and then callout to System B (from System A only) –  logontokartik Jan 11 '13 at 15:09
1  
Are you testing your rest method by making an httprequest from anonymous apex by any chance? the callout loop error only happens when you try and make a callout to another salesforce method from a "call-in". If you are calling out to an external system it should work. –  Greg Grinberg Jan 15 '13 at 14:38
1  
Here's a business reason: System A doesn't have credentials for System B, but the Salesforce instance does. System A authenticates with Salesforce, which then retrieves data from System B to supply to System A. –  tomlogic Feb 1 '13 at 22:48
    
workaround: if it were a mission critical one-off using systems you control, an HTTP proxy service (eg squid) could drop the Sfdc-Stack-Depth header before forwarding the requests ;-) –  bigassforce Feb 1 '13 at 23:04

2 Answers 2

No, there is not an immediate workaround to this :-(

The mechanism by which they measure that 'callout depth' is by transmitting an HTTP header on requests originating from Apex, Sfdc-Stack-Depth: 1 - if you try and trick the platform by explicitly setting this header to '' etc, you'll find the value is very sticky!

Unfortunately for us, there is a good business reason behind this "feature" on Salesforce' part. It is by design, to prevents callouts from blocking threads between multiple orgs / instances. sequence diagram

(hopefully this sequence diagram illustrates the intention; as an HTTP callout could take a while, the number of loopback connections is restricted to 1, otherwise imagine the DoS implications)

You might be able to overcome this issue if your B callout were read-only and its contents were updated infrequently.

You could schedule a batch process to regularly perform the callout and avail its response in a Document (or such). Then read that Document when responding to A, decoupling the two. But I admit that may be unlikely in your case...

share|improve this answer

@user31's answer is absolutely incorrect (or I am misunderstanding the question). There is nothing preventing you from making callouts from Apex REST methods to external systems. Here is some sample code:

@RestResource(urlMapping='/restexample/')
global with sharing class RestExample 
{
    @HttpGet
    global static string doGet() 
    {
        HttpRequest req = new HttpRequest();

        req.setMethod('GET');
        req.setEndpoint('https://www.google.com');
        system.debug('request body: '+req.getbody());

        HTTPResponse res = new http().send(req);

        return res.getBody();
    }
}

Note that you cannot make callouts to Salesforce as that will give you the callout loop error.

You can test this code through curl or something similar. Testing it through anonymous Apex will give the callout loop error as you are making a callout from within Salesforce to Salesforce.

share|improve this answer
    
Ya got me there grigriforice; in my answer I've made the unstated assumption that System A or System B is a Salesforce system ;) hopefully Prafulla Patil can respond to your comment on the question itself to clarify this. –  bigassforce Jan 15 '13 at 23:00
    
@user320 yeah, that definitely might be the case but he called them both external systems. Didn't want anyone else to think this was impossible. –  Greg Grinberg Jan 15 '13 at 23:23
1  
I can confirm that a RESTful interface called from a Force.com site cannot make a web callout, and I'll likely have to modify my workflow to use an @future method for that callout. Thankfully, in my case, I don't need to respond with data from the callout. –  tomlogic Feb 1 '13 at 22:53
2  
And I can now confirm that @future isn't enough to break the loop. I still get a CalloutException from my FutureHandler. I can see where Salesforce would want to avoid some runaway processes spawning connections between instances, but this is starting to make my life more difficult. –  tomlogic Feb 1 '13 at 23:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.