Andy Harvey Andy Harvey - 3 years ago 219
jQuery Question

How to cache an external json request?

In a WordPress theme I am displaying info from an external JSON API. How can I cache this data to improve page load times.

I have a jQuery function

var url = 'http://my.api.com/'
$.getJSON(url)
.done( function(data) {
#display this data
})
.fail( function( jqXHR, textStatus, error) {
#handle errors
});


Does jQuery provide a way to cache these requests? Or should I be handling this within WordPress somehow (perhaps writing the response to a JSON file on the server)?

Answer Source

Depending on the API and the context in which calls are made, you can use the server to complete these API calls rather than requiring the client to do it. Doing the former means you can utilise caching through the database, but will mean a little more strain on the server as it's the one now completing all of the requests.

This may only really be worthwhile if it's not user-specific information. That said, I'm a pretty big proponent of server-side caching of anything involving an external web service.

You'll probably want to leverage some of WordPress' built-in functionality, specifically including:

WP_Http This is WordPress' nifty built-in HTTP library which you can use to talk to the API.

Transients API Again - super nifty. Lets you store and retrieve self-expiring data to and from the local database.

A quick implementation (untested, please let me know if there are issues) is as follows:

define( 'HOURS', 60 * 60 );

function get_api_info( ) {

    global $apiInfo; // Check if it's in the runtime cache (saves database calls)
    if( empty($apiInfo) ) $apiInfo = get_transient('api_info'); // Check database (saves expensive HTTP requests)
    if( !empty($apiInfo) ) return $apiInfo;

    $response = wp_remote_get('http://my.api.com');
    $data = wp_remote_retrieve_body($response);

    if( empty($data) ) return false;

    $apiInfo = json_decode($data); // Load data into runtime cache
    set_transient( 'api_info', $apiInfo, 12 * HOURS ); // Store in database for up to 12 hours

    return $apiInfo;
}

Then, you just need to call get_api_info() anywhere in your code to retrieve the data you need. If you call the function multiple times in the same request/script, it will still only yell out to the database once. If you call the function in multiple requests within a 12 hour period, it will only send the API request once.

Talk about efficiency!

Of course I'd also recommend having a class implementation for this, so you can use instance variables rather than globals to store data, but that's just getting nitpicky.

Hope that helps!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download