APIConnect

APIConnect is a Javascript class that provides a simple way to interact with APIs, specifically those hosted on other domains. Setup is as simple as creating the instance, specifying the domain, connecting the route, and running it. APIConnect works in all major browsers with jQuery as its only dependency, and is now available on npm!

var api = new APIConnect(); api.domain('graph.facebook.com'); api.connect(':object_id'); api.getObject({ object_id: page_id }).then(displayJSON);

Connecting Routes

Any route can have any number of params in the base URL (contexts). These contexts are always optional, and will only be added if they exist in the params object when the route is called.

Once the route is connected, calling it is as simple as calling a camelized method on the instance. When making the call, the first argument is the params object, and the second argument is for "options". Here you can specify options for both APIConnect as well as any valid option for jQuery.ajax, meaning all standard callbacks will work.

var api = new APIConnect('graph.facebook.com'); api.connect(':object_id'); api.getObject({ object_id: page_id }, { complete: displayJSON });

API calls also pass back jQuery deferred objects, so these can be used as well.

var api = new APIConnect('graph.facebook.com'); api.connect(':object_id'); api.getObject({ object_id: page_id }).then(displayJSON);

Both params or options can also be made "global" or instance-wide by specifying them directly on the instance. They will be applied to all routes (but can be overwritten with local params/options).

var api = new APIConnect('graph.facebook.com'); api.params({ access_token: app_access_token }); api.options({ complete: displayJSON }); api.connect(':object_id'); api.getObject({ object_id: page_id });

The 4 main HTTP verbs, "GET", "POST", "PUT", and "DELETE", are allowed in routes, and map to humanized verbs "get", "create", "update", and "destroy", respectively. "GET" is the implied default.

This code is actually posting to a live Facebook page through APIConnect!

var api = new APIConnect('graph.facebook.com'); api.param('access_token', app_access_token); api.connect('POST :id/feed'); var message = "Hello from APIConnect! It's " + new Date().toString(); api.createFeed({ id: page_id, message: message }, { complete: displayJSON });

The camelized method name is a combination of the humanied HTTP verb and the last non-parameter fragment in the route. In the examples, a "non-parameter fragment" is photos as opposed to a "parameter fragment" :photo_type, etc. If no non-parameter fragments exist, the last parameter fragment will be used instead.

If this is still not good enough, the entire method name can easily be overridden using the as option when connecting the route.

var api = new APIConnect('graph.facebook.com'); api.connect(':object_id/photos/:photo_type', { as: 'getImages' }); api.getImages({ object_id: page_id, photo_type: 'profile' }, { complete: displayJSON });

Params can also be "burned in" when connecting routes, allowing even more expressive statements.

var api = new APIConnect('graph.facebook.com'); var p = { photo_type: 'profile' }; api.connect(':object_id/photos/:photo_type', { params: p, as: 'getProfileImages' }); api.getProfileImages({ object_id: page_id }, { complete: displayJSON });

"resource" serves as a shortcut to all 4 HTTP verbs.

api.resource('member'); api.getMember(); // GET http://domain/member.json api.createMember(); // POST http://domain/member.json api.updateMember(); // PUT http://domain/member.json api.destroyMember(); // DELETE http://domain/member.json

Members of these routes can be limited using only and exclude.

api.resource('member', { only: 'show,update' }); api.getMember(); // GET http://domain/member.json api.updateMember(); // PUT http://domain/member.json api.resource('member', { exclude: 'show,update' }); api.createMember(); // POST http://domain/member.json api.destroyMember(); // DELETE http://domain/member.json

If a resource is a collection, passing collection: true in the options for "resource" will create standard collection routes including an "index" method.

api.resource('status', { collection: true }); api.getStatus(); // GET http://domain/status.json api.getStatus({ id: 3}); // GET http://domain/status/3.json api.createStatus(); // POST http://domain/status.json api.updateStatus({ id: 3 }); // PUT http://domain/status/3.json api.destroyStatus({ id: 3 }); // DELETE http://domain/status/3.json

If collection is omitted, it will attempt to be intelligently detected by the pluralization of the resource passed.

api.resource('members'); api.getMembers(); // GET http://domain/members.json api.getMembers({ id: 3}); // GET http://domain/members/3.json api.createMembers(); // POST http://domain/members.json api.updateMembers({ id: 3 }); // PUT http://domain/members/3.json api.destroyMembers({ id: 3 }); // DELETE http://domain/members/3.json

Options

Options are passed in when making the call, and can be overridden there, however instance-wide options are set on the object itself.

api.option('headers', { myCustomHeaderName: 'myCustomHeaderValue' }); api.options({ statusCode: { 404: function() { alert('Page not found!'); } } });

Additionally the basic options "domain", "protocol", "port", "timeout", "cors", and "jsonp" can be set directly on the instance. When setting options, the instance itself will be returned, allowing method-chaining just like jQuery objects.

api.domain('localhost'); api.port('4000'); api.cors(false);

All such options are both getters and setters. Passing no arguments will return their current value.

api.domain(); // "localhost" api.port('4000'); // "4000" api.cors(false); // false

Cross-domain ajax and JSONP

APIConnect will by default attempt to use CORS (cross-origin resource sharing). For this to work, the API you're working with needs to be sending the correct response headers. If your calls are returning a 200-level response but no data is coming in, most likely CORS is not supported and needs to be disabled.

Turning off CORS support will fall back to JSONP, which also needs to be enabled on the API side.

var api = new APIConnect('graph.facebook.com'); api.cors(false); api.connect(':object_id'); api.getObject({ object_id: page_id }).then(displayJSON);

Certain older browsers (earlier versions of IE, etc) do not support CORS. In this case, APIConnect will fall back to JSONP if the request is on another domain. This means that if both CORS and JSONP are enabled on the API server, all browsers will work with APIConnect of the box. However if JSONP is not supported, the request must be on the same domain or it will fail outright.

Advanced

If you have many routes with the same context you can hold onto it so as not to repeat yourself.

api.context(':user', function() { api.connect('tasks'); api.connect('images'); api.connect('profile'); // ... });

Results from an api call can be cached locally for the duration of the page load. Only GET requests will be cached and only if the params match exactly. If cached, the calls will resolve successfully immediately.

api = api || new APIConnect('graph.facebook.com'); api.connect(':object_id'); api.getObject({ object_id: page_id }, { cache: true }).then(displayJSON);