+ Start a Discussion

Help! New to SFDC. HTTP Post on save.

I am having a love hate relationship with the extensive SFDC documentation.  I love there is sooo much documentation, I hate there is sooo much documentation.  Here is my issue....


My boss just walked into my office and said you administer the Accounting solution right??, ok, we need data to get into the accounting system from SFDC. Take care of it. :)


Well...I have never used salesforce, apex, and don't know where to start......


Here is what I want to do.  I have built a custom object with 10 fields on it. When the user hits save, I need to construct an http post request to a non-sfdc address that contains structured XML for the accounting solution gateway and contains the values of my 10 fields.


I was hoping someone could just point me in the right direction where to start.  Any help would be greatly appreciated.


Triggers? Apex? Workflow? Outbound message?



I had to do something similar.  I would look for "HTTP Callout" or "HTTP (RESTful) Services Classes".  My quick-and-dirty solution used an HTTP GET rather than POST, but I would bet you could use it as a starting point:


        HttpRequest req = new HttpRequest();
        req.setHeader('Host', 'some.where.com');
req.setHeader('X-MyVariable', 'my-value');
        Http http = new Http();
        try {
            HTTPResponse res = http.send(req);
            if ( res.getStatusCode() != 200 )
                WSResult r = new WSResult(false);
// My server supplies an 'X-Message' header on error
                r.errorMsg='Error performing callout: ' + res.getHeader('X-Message');
                return r;
        catch ( System.CalloutException e )
            WSResult r = new WSResult(false);
            r.errorMsg = e.getMessage();
            return r;

        WSResult r = new WSResult(true);
        r.errorMsg = 'Success';
        return r

For your needs I'd look to write a trigger (fire on after insert & after update) that invokes your POST callout. The POST callout will have to be written separately, within a static method in an external class with the @future annotation to make it asynchronous, because Apex does not allow synchronous callouts in a trigger context.


@future methods can only take primitives as arguments, so you'll have to construct your payload as a String, in your trigger, before you invoke the callout. 


Last I looked at the XML Doc utils in Apex (which was ~ a year ago), it was kinda disappointing -- there was no way to create an XML representation of an arbitrary Apex Class or SObject without writing lots of custom code. Don't know if thats changed -- however, I've read that there's new JSON Utils in the recent release that seem to do cool things like that (except in JSON, instead of XML). Since you probably have access to a decent JSON library in your destination system, I'd try to go that route if the XML utils still don't provide satisfaction.


Since your callout would be responsible for sync'ing data to your external system, and the callout itself will be executed separately from your Trigger (i.e. there's no guarantee the sync will succeed), I'd look into adding a "LastSynced" DateTime custom field to your custom object that should be updated (with current system time) as the last action in your @future method. That opens up the possibility of implementing a nightly batch process to figure out which objects were updated by users but never go sync'd (e.g. a LastSynced that's null of NOT greater than the record's LastModified DateTime is likely due to a callout  failure), and then trying to sync again. That way you have a more robust syncing solution (also consider error handling/email alerts). 


One final consideration -- making the above efficient for bulk trigger executions (e.g. 200 records at once, without exceeding governor limits). You'd have to look into constructing your payloads as a List of Strings, and then sending that into the @future method (hopefully they allow large-ish arrays of primitives).