API Best Practices

I’m working on an app where I want to provide an API for Ajax requests and I’m struggling to figure out the best way to go about it. My initial idea was to create a package named API under handlers and for every handler that I wanted to provide access to via Ajax I’d have an specific API handler and action like this:

// This is /api/account/list. Provides an API to the Account handler, list action

function list(event){
var rc = event.getCollection();

runEvent(“account.list”);

event.renderData(type = “json”, data = {
someData = rc.someData // the data I want to render

});
}

This would definitely work and is easy to implement but most every function would be very extremely similar I’d guess. Some functions might be a little different but mostly they’d be the same. Plus I’d have to manually create a bunch of API handlers. Not a huge deal. I’m just looking for perhaps a better way.

On the other hand, I’ve considered making some kind of generic API handler that would take a request like /api/account/list and run the account.list event automatically then convert the RC scope to JSON/XML for use. The problem I see here is that the RC scope contains a lot more than I need to actually return. Plus, it might contain complex entities that don’t always serialize well without a little massaging.

I’d accomplish this by adding a route:
addRoute(pattern="/api/:targetHandler/:targetAction",handler=“API”,action=“execute”);

And then having an API handler like this:

component{
function execute(event){
var rc = event.getCollection();

if(!structKeyExists(rc,“format”) || trim(rc.format) == “”){
throw(“Invalid format extension.”);
}

runEvent("#rc.targetHandler#.#rc.targetAction#");

event.renderData(type = rc.format, data = rc);
}
}

In the CB docs I did notice under the What’s New section this sample route which looks a lot like the second option I described. Is anyone doing something like generic API handler?

// route with custom constraints
addRoute(pattern="/api/:format/",
		 handler="api",
		 action="execute",
		 contraints={
			format = "(xml|json)"
		 });

All this code is simplified and I’d have more error checking among other things but right now I’m just trying to figure out the best way to tackle this. So, all that said, how does everybody else handle this problem?

I’ve recently completed a project that delivered an API for my favorite video web site. I’ll be blogging on it this weekend.

Aaron Greenlee

There is no hard convention here, and it is going to be what best suits you at the moment. The API way can be better used if you want to be able to keep the two separated, and still be able to reuse code, as in your example you provided.

I also want to say that I would prefer this method now, rather than later. The reason behind this is that future maintenance and support will be kept to a minimum, if the requirements for the API get changed.

But again it is best suited to the way that is comfortable for you, for example the API might want to get locked down by get requests only, which you can’t do with the other event handler. But you might not even care about this for your site, or Application.

So the question now is you chose too separate now, was there a reason that you did, and answering that might answer how you do it in the future as well.