Saturday, March 8, 2008
I talked about delegating rendering in Symfony for creating a JSON API. Now here’s a consumer: an Orkut opensocial gadget:
MobshareOrkutAPI = {
api_url: 'http://api.mobshare/api.php',
cache_time: 0, //0 to disable
makeCachedRequest: function(url, callback, params, refreshInterval) {
var ts = new Date().getTime();
var sep = "?";
if (refreshInterval && refreshInterval > 0) {
ts = Math.floor(ts / (refreshInterval * 1000));
}
if (url.indexOf("?") > -1) {
sep = "&";
}
url = [ url, sep, "nocache=", ts ].join("");
gadgets.io.makeRequest(url, callback, params);
},
call: function(module, action, params, callback) {
var options = {};
options[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
this.makeCachedRequest(this.api_url + '/' + module + '/' + action + '?' + params, callback, options, this.cache_time);
}
};
makeCachedRequest has been plaigarized from the Opensocial documentation and it’s very useful to bust the cache for requests. Also, notice this line for setting the content-type to JSON:
options[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
This is how we access that API, a code fragment:
...
authenticate: function(alias, mobile_no, password) {
MobshareOrkutAPI.call('user', 'authenticate',
'alias=' + encodeURIComponent(alias) + '&mobile_no=' + encodeURIComponent(mobile_no) +
'&password=' + encodeURIComponent(password),
MyOrkutApp.login
);
}
...
login: function(orkut_response) {
response = orkut_response.data;
data_success = response['success'];
data_error = response['error'];
if(data_success) {
html = '<h2>Login Successful!</h2>';
html += '<p>Welcome: ' + data_success.name + '!</p>';
} else if(data_error) {
html = '<h2>Login Unsuccessful!</h2>';
html += '<p>' + data_error + '!</p>';
}
document.getElementById('mobshare_login').innerHTML += html;
},
...
Note that orkut_response.data is automatically set by Orkut because you passed in the JSON content type; it parses the data received and creates a javascript object. Cool, ain’t it? It’s very easy to create a proper interactive Opensocial app this way.
Tags: api • application • development • javascript • json • opensocial • orkut • web
Comment! |
Permalink
Thursday, March 6, 2008
Warning: pretty advanced Symfony ahead: if you’re not familiar with the framework, this wouldn’t make sense.
I recently developed a bare-bones API for Mobshare (it’s not yet live), and to keep everything clean, I abstracted away the rendering bit from the controller to an external class. It ended up being a sweet solution, so here it is!
I wanted this to be a JSONP API (the major use case would be a JS client, and parsing XML etc. via JS is a pain. Besides JSON is much shorter over the wire). I didn’t want to rewrite a lot of code: checking for a callback parameter and wrapping the returned string around the JSON output was just begging to be refactored away. So here it is, a generic Symfony JSON API wrapper class:
<?php
class JSONPAPI {
const CALLBACK_PARAMETER = 'callback';
var $status;
var $data;
var $callback;
public function __construct($status, $data) {
$this->status = $status;
$this->data = $data;
$callback_parameter_value = $this->getCurrentAction()->getRequestParameter(self::CALLBACK_PARAMETER);
if($callback_parameter_value)
$this->callback = $callback_parameter_value;
}
public function render() {
$render_text = json_encode(array($this->status => $this->data));
if($this->callback)
$render_text = $this->callback . '(' . $render_text . ');';
$this->setJavascriptHeaders();
return $this->getCurrentAction()->renderText($render_text);
}
//hack to get the current action
private function getCurrentAction() {
return sfContext::getInstance()->getActionStack()->getLastEntry()->getActionInstance();
}
private function setJavascriptHeaders() {
sfContext::getInstance()->getResponse()->setParameter('Content-Type', 'application/javascript', 'symfony/response/http/headers');
}
}
The bits of magic here are the getCurrentAction() function and the render() call. It works on one very simple idea: everything in Symfony can be accessed from the sfContext::getInstance() object, you just need to dig deep enough.
Once you write this boiler-plate code, using it is very elegant. First, subclass it for your API:
<?php
require_once('JSONPAPI.class.php');
class MobshareAPI extends JSONPAPI {
}
And then, use it like so within your controller:
<?php
class userActions extends sfActions
{
public function executeAuthenticate() {
$valid_user = UserPeer::authenticate($this->getRequestParameter('alias'),
$this->getRequestParameter('mobile_no'), $this->getRequestParameter('password'));
if($valid_user instanceOf User) {
$success = new MobshareAPI('success', $valid_user->toArray());
return $success->render();
} else {
$error = new MobshareAPI('error', 'Authentication failed: Alias, mobile number or password invalid.');
return $error->render();
}
}
}
Note: the rendering has been delegated to the $success and $error MobshareAPI objects. This allows for a really maintainable API. Adding functionality is much simpler since you don’t have to worry about the boilerplate.
You end up calling the API like this:
http://api.mobshare/user/authenticate?alias=vish&password=xxx&callback=handler
and you get back data which looks like this:
handler({"success":{"alias":"vish","name":"Vishnu Gopal","photo_mini": ...);
Note that callback handling is done entirely by the API and the controller needn’t worry about this parameter at all!
Tags: api • cool • development • json • jsonp • PHP • symfony • web
Comments (4) |
Permalink
Sunday, September 9, 2007
So here’s a SlideShare/Twitter Mashup (command-line ruby code) that does these things:
- Gets buzzwords from Twitter. It does this by analyzing tweets and getting popular words (filtering out common ones) with the Twitter API.
- Gets the most popular buzz word and searches the SlideShare tag database with it (using the SlideShare API).
- Prints out the buzzword and the slideshows that’s associated with it.
The source code might not be a great example of filtering and getting popular words, but it’s a good demo of how simple the Twitter and SlideShare APIs are (REST yay) and how easy Hpricot makes parsing XML docs.
There’s a zip (with the source code, common_words.txt, twitter_words.txt) here: slideshare_twitter.zip. Enjoy.
Tags: api • code • development • slideshare • twitter
Comments (1) |
Permalink