[SalesForce] restful call to external analytics API via visualforce/apex

So I'm trying to access Woopra analytic's restful API via apex/visualforce. I am wondering a couple of things:

1) The API returns a JSON object via the usual POST/GET method… would it be best to call the API through apex, or would it be better (or even possible) to do a jquery/ajax style call from a VF page?

2) IF I were to need to do this in apex, how would I translate the following:

var params = {
  website: 'yourwebsite',
  segment: [
    {
      did: {
        operator: 'AND',
        filters: [
          {
            scope: 'actions',
            key: 'name',
            match: 'match',
            value: 'quote'
          }
        ]
      },
      are: {
        operator: 'AND',
        filters: []
      }
    }
  ]
  // optional parameters
  offset: 0,
  report_id: -1 //paging   
};

$.ajax({
  type: 'POST',
  url: 'http://www.woopra.com/rest/search'
  crossDomain: true,
  beforeSend: function(wrq) {
    wrq.setRequestHeader('X-Api-Version', '2.0');
    wrq.setRequestHeader('X-Access-Id', APP_IDXXXXXXXX);
    wrq.setRequestHeader('X-Access-Secret', SECRET_KEYXXXXXXX);
  },
  data: params
});

my best shot is:

    public global class WoopraData
    {
        @future (callout=true)
           public string json;
            public string response;
        public static void sendRequest() {

            HttpRequest req = new HttpRequest();
            HttpResponse res = new HttpResponse();
            Http http = new Http();

            req.setEndpoint('http(s)://www.woopra.com/rest/report`');
            req.setMethod('POST');
            req.setBody('website=XXXXXXXXX.com'+'&segment=did: {operator: \'AND\', filters: [ {scope:\'actions\', key : \'name\', mathch:\'match\', value: \'quote\'}]}, are: {
        operator: \'AND\',
        filters: []
      }
    }
  ]);
            req.setCompressed(true); // otherwise we hit a limit of 32000

            try {
                res = http.send(req);
                json = res.getbody();
                response = convertresponst(json);
            } catch(System.CalloutException e) {
                System.debug('Callout error: '+ e);
                System.debug(res.toString());
            }

        }

        public string convertresponse(string json)
        {
           try{
            JSONObject j = new JSONObject( json );
           }
           catch(Exception e){}

            results = j.getValue('totalvisits').values[0].dnum.format();
            return response;
        }
        public static testMethod void testMe() {
            WebServiceCallout.sendRequest();
        }
    }

… How would I go about 1) writing this correctly, and 2) displaying this on a VF page (very simply, I just want to get the data to appear)?

Any push in the right direction will help immensely (mainly, trying to translate the API call into APEX, or helping me figure out how ot make the call directly from the page.

Here is the API documentation:

http://www.woopra.com/docs/developer/analytics-api/

And My references so far are:

http://blogs.developerforce.com/developer-relations/2012/10/not-calling-the-rest-api-from-javascript-in-visualforce-pages.html

http://developer.force.com/cookbook/recipe/accessing-docusign-api-from-salesforcecom-to-send-contracts-for-esignatures

http://techblog.appirio.com/2010/01/calling-rest-web-service-json-with-apex.html

http://wiki.developerforce.com/page/Apex_Web_Services_and_Callouts

http://blog.jeffdouglas.com/2009/03/16/restful-web-service-callout-using-post/

Best Answer

Glad you showed us everything you tried. You are really close, man!

  1. go to Setup > Remote Site Settings and create an entry for http://www.woopra.com/

  2. create the following Visualforce Page and Apex Class, then view the page at /apex/Woopra

  3. see if you get a 403 like I do ;-) then substitute your real credentials into the request headers

  4. play until it gives you 200 OK, then remove the System.assert... (that was for debug)

  5. eyeball the response data, and how you might go about parsing / displaying it...

Don't forget to update us! Here's how you might do your API call in Apex - try:

WoopraController.cls

public class WoopraController {

  public String Headers {get; set;}
  public String Response {get; set;}

  public void doRequest() {
  String data = '{'
    + '\n' + '"website":"yourwebsite",'
    + '\n' + '"segment":['
    + '\n' + '  {'
    + '\n' + '    "did":{'
    + '\n' + '      "operator":"AND",'
    + '\n' + '      "filters":['
    + '\n' + '        {'
    + '\n' + '          "scope":"actions",'
    + '\n' + '          "key":"name",'
    + '\n' + '          "match":"match",'
    + '\n' + '          "value":"quote"'
    + '\n' + '        }'
    + '\n' + '      ]'
    + '\n' + '    },'
    + '\n' + '    "are":{'
    + '\n' + '      "operator":"AND",'
    + '\n' + '      "filters":[]'
    + '\n' + '    }'
    + '\n' + '  }'
    + '\n' + '],'
    + '\n' + '"offset":0,'
    + '\n' + '"report_id":-1' +
  '}';

  System.HttpRequest request = new System.HttpRequest();
  request.setBody(data);
  request.setMethod('POST');
  request.setEndpoint('http://www.woopra.com/rest/search');
  request.setHeader('X-Api-Version',   '2.0');
  request.setHeader('X-Access-Id',     'APP_IDXXXXXXXX');
  request.setHeader('X-Access-Secret', 'SECRET_KEYXXXXXXX');

  System.HttpResponse response = new System.Http().send(request);
  System.assert(false, response); //remove this once you fix the 403
  this.Response = response.getBody();
  }
}

Woopra.page

<apex:page controller="WoopraController" action="{!doRequest}" contentType="text/plain">
  {!Headers}
  {!Response}
</apex:page>