Advertisement
Creative Coding

Building a WordPress-Friendly API Wrapper: Foundations

by

When building a web site or web application, it's a pretty common requirement that you might need to pull in data from third-party site or application. If that site or application has an API, this is an excellent way to obtain the data needed. So, let's take a look at how to do this with WordPress.


What Is an API?

Before we get into the nitty gritty, let's make sure we're all up to speed with a couple of things, starting with what an API is.

For the purposes of this tutorial, when we say "API" (application programming interface) we specifically mean what Wikipedia classes as a "Web API":

A server-side web API is a programmatic interface to a defined request-response message system, typically expressed in JSON or XML, which is exposed via the web — most commonly by means of an HTTP-based web server.

To put it more simply: an API is a way for one application to ask another application for predefined information in (most often) JSON or XML format, over a standard web URL.

Got it? Ok, next…


What Is a "Wrapper"?

Making a request to an API can involve a number of steps, and you may want to add in extra steps such as error checking, caching, validating, etc.

Wikipedia defines a Wrapper function as follows:

A wrapper function is a function in a computer program whose main purpose is to call a second function with little or no additional computation. This is also known as method delegation. Wrapper functions can be used for a number of purposes.

That definition may make it sound a little like wrappers are just redundant code, but they're actually far from it.


Important Considerations

Creating a wrapper for an API allows us to be friendly to everyone. Let me explain:

  • APIs often have a "rate limit", which is the number of times and frequency at which you can contact them. Contacting an API more than the rate limit specifies can get you blocked, and for information that doesn't change that regularly, it creates unnecessary load on the API. By creating a wrapper, we can implement our own caching so we contact the API less frequently.
  • Further to this, if we make a request to an API with information that's incorrectly formatted or incomplete, it's a wasted request. We should make sure the request we send is complete, and formatted correctly, as best we can before we send it.
  • Sometimes an API may send information back that's not quite formatted in the simplest way for us to use. Having a layer in between the developer and the API allows the chance to massage the data as needed before the developer gets it.
  • Developers also shouldn't have to repeat themselves more than necessary. If we bundle all the steps involved in making an API call up into a wrapper, this simplifies development using the API in question.

Wrappers make dealing with APIs developer-friendly, and API-friendly.

So the particular things we're going to get our API to handle are:

  • Making a call to the API when the developer requests information
  • Checking to ensure valid data is sent to the API
  • Checking if the API returned an error rather than useful data, and dealing with it accordingly
  • Caching responses from the API so that if the same request is made in a short space of time, we don't have to contact the API
  • Adjusting the returned data for simplified usage

We'll also be doing these things in a WordPress-friendly way, such as utilising transients for caching, and wp_remote_request for sending the API requests.


Building the Foundation

The API we're going to be using for this tutorial is the Envato Marketplace API. This API provides information on the items and users on the Envato Marketplaces, such as ThemeForest, CodeCanyon, and others.

We'll be basing our development around Public Sets, seen in the Envato Marketplace API documentation. Also, note the TTL (time to live) column, which is essentially the "rate limit" for this API. As the data only changes with this frequency, there's no point requesting any given set more often than the TTL specified.

So let's begin building the base class for communicating with this API.

1. File Structure

Because this will eventually be inside an example plugin, which we'll get to later, let's create that file structure and build the API wrapper inside.

Our plugin will be showing the results of the "random-new-files" API set, so we'll call it "Wptuts+ Random New". So inside your wp-content/plugins/ directory, go ahead and create a directory called wptuts-random-new.

Now inside that directory, make a new directory called envato-api-wrapper, and a file inside that called class-envato-api-wrapper.php. This whole directory will then be able to be copied into other projects that need to use this API in future too.

2. Class and Basics

Open the *class-envato-api-wrapper.php file, and let's begin.

First, let's define our class:

<?php
class Envato_Marketplace_API {

    // All the things

}

We're also going to need a simple way to test this wrapper as we build it, without having to load all of WordPress. So what I've done, is just create an index.php file in the envato-api-wrapper directory, with the following content:

<?php
// We want to see errors during debugging
error_reporting(E_ALL);
ini_set('display_errors', '1');

// We need to use some WordPress functions
require( '../../../../wp-load.php' );

// And we need our wrapper!
require( 'class-envato-api-wrapper.php' );

// Initialise our wrapper
$envato_api = new Envato_Marketplace_API();

Now you should be able to browse to http://localhost/wp-content/plugins/wptuts-random-new/envato-api-wrapper/ (replace "localhost" with your own development environment). You shouldn't see anything yet though, because wrapper doesn't do anything yet. If you see an error though, double-check the code.

Note: don't forget to remove this file, or blank it out, before deploying to production!

3. Where to Send Requests

The first thing you're going to need before making a request to an API, is the base URL to use. This URL will then have various information added to it before sending the request.

In the case of the Envato Marketplace API, we'll use the following URL:

http://marketplace.envato.com/api/edge/set.json

In this URL there are two main variable bits of information: edgde and set.

The position of edgde represents the version of the API we want to use, and in this specifically the most current version. It will be the same in all requests, however if something changes and we wanted to use an older version, we could swap it out for v3 instead for example.

The position of set represents the actual data set we're requesting. The word "set" is a placeholder, and we'll replace it with the relevant details when making a specific request.

Let's add a property of $api_url to our class with this value:

<?php
class Envato_Marketplace_API {

    protected $api_url = 'http://marketplace.envato.com/api/edge/set.json';

}

Note that we've indicated this property is 'protected'. We've done this because we don't want the URL to be changed directly by other code outside of our wrapper.

4. Making a Request

Before we try making an specific request, we'll add a generic method to our class that will handle making any request. We'll call it remote_request, and all it will need is a URL to send the request to.

protected function remote_request( $url ) {

    // Firstly, if the URL is empty, don't send a request
    if ( empty( $url ) ) {
        return false;
    }

    // Make the request
    $request = wp_remote_request( $url );

    // Check that WordPress was able to send the request, otherwise error
    if ( is_wp_error( $request ) ) {
        echo $request->get_error_message();
        return false;
    }

    // Decode the response so we can use it
    $data = json_decode( $request['body'] );

    if ( $request['response']['code'] == 200 ) {
        return $data;
    }
    else {
        return false;
    }

}

Note that again we've indicated that this method is 'protected', to prevent it being called directly from outside our class.

Now to be able to test that the request is working, we'll add our first API method. In this case, we'll go with the random-new-files set, which is the one we'll use later in our example plugin.

Add the following method to our class:

public function random_new_files( $marketplace ) {

    // Create a URL for this request by replacing the 'set' placeholder with the set and any required parameters. In this case, the slug of an Envato marketplace
    $url = preg_replace( '/set/i', 'random-new-files:' . $marketplace, $this->api_url );

    // Send a request to the API
    $results = $this->remote_request( $url );

    return $results;

}

To test this new method, and by extension the API request method, add the following line to our debugging index.php file:

echo '<pre>' . print_r( $envato_api->random_new_files( 'themeforest' ), true ) . '</pre>';

Now you should get output in your browser similar to this:

stdClass Object
(
    [random-new-files] => Array
        (
            [0] => stdClass Object
                (
                    [id] => 4860464
                    [item] => Empire - Business, Portfolio HTML 5 Template
                    [url] => http://themeforest.net/item/empire-business-portfolio-html-5-template/4860464
                    [user] => designthemes
                    [thumbnail] => http://1.s3.envato.com/files/57931279/thumb-html.png
                    [sales] => 0
                    [rating] => 0.0
                    [cost] => 15.00
                )

                ...

            [9] => stdClass Object
                (
                    [id] => 4852371
                    [item] => eplie | Mobile HTML/Css Portfolio Template
                    [url] => http://themeforest.net/item/eplie-mobile-htmlcss-portfolio-template/4852371
                    [user] => cosmincotor
                    [thumbnail] => http://1.s3.envato.com/files/57831617/thumbnail.png
                    [sales] => 3
                    [rating] => 0.0
                    [cost] => 8.00
                )

        )

)

Assuming you saw something like the above, that means it's working and you've gotten data back from the API. Success!


Next: Caching, Error Handling, and a Widget

Now we've gotten the basis of the wrapper done, things are under way. In the next part, we'll finish off the wrapper and build a widget that utilises it.

Also, keep in mind that while this wrapper is being built for the Envato Marketplace API, the same concept (and a lot of the same code so far) can be used to create a wrapper for any RESTful API.

Let us know in the comments what ideas you have for working with APIs and WordPress.

Related Posts
  • Code
    Plugins
    Distributing Your Plugins in GitHub with Automatic UpdatesSensorsthumbnail
    This article will teach you that, with a little creative coding, you can host your own WordPress plugins in GitHub while still retaining the automatic update feature.Read More…
  • Code
    Creative Coding
    Using WordPress For Web Application Development: Available Features, Part 7: CachingApplication foundation 400
    When it comes to building web applications, one of the most important things that we have to constantly be mindful of is performance. As they say, performance is a feature. And regardless of if you're a designer, developer, or a user, you know this intuitively to be true: When it comes to applications, we hate waiting. We get frustrated when things don't perform fast enough, or we have to wait longer than we believe that we should.Read More…
  • Code
    Creative Coding
    Using WordPress For Web Application Development: Available Features, Part 6: URL Rewriting (or Routes)Application foundation 400
    One of the nicest things about modern web application development frameworks is that they provide a way to generate really clean routes—or URL schemes—that map to the conceptual model of how the application is structured.Read More…
  • Code
    JavaScript & AJAX
    Getting Into Ember.js: Part 5Getting into ember
    Editor's Note: The Ember.js team has shifted to an expedited release schedule and as of this publication date are on version 1.2.0. This tutorial was written pre-v1.0 but many of the concepts are still applicable. We do our best to commission timely content and these situations happen from time-to-time. We'll work to update this in the future. In part 3 of my Ember series, I showed you how you can interact with data using Ember's Ember.Object main base class to create objects that define the methods and properties that act as a wrapper for your data. Here's an example:Read More…
  • Code
    Plugins
    Communicating With the WordPress.org Plugin APIWordpressdotorg plugin api border 400
    Over the last few weeks I have been wondering on how to possibly pull data about my plugins hosted on WordPress.org and display it on my website. The first thing that came to mind was "Web Scrapping" but quite frankly this is a lot of work, feels like going back in time, and is not something a good web citizen should do. In some cases, it could be illegal.Read More…
  • Code
    Creative Coding
    A Look at the WordPress HTTP API: A Practical Example of wp_remote_postDiagram http api
    In the previous article, we reviewed the previous articles regarding GET requests, the native PHP facilities for making requests, and reviewed WordPress wp_remote_post API function along with the arguments that it offers. In this article, we're going to make use of wp_remote_post such that we're actually able to see it in action. Remember that this - like wp_remote_post - is part of the HTTP API of which there are other functions worth reviewing. But, for now, we're going to put wp_remote_post to work. Specifically, we're going to do the following: When the page loads, we're going to submit some information to a custom script The script will examine the information and return it to our page We'll then display the data on the page Sure, it's a bit of a contrived example but it will give us the experience of creating a separate PHP script that can be used for operations triggered by the use of wp_remote_post. Anyway, for the purposes of this example, we are going to use the PHP $_SERVER collection to log when the user has submitted their preference rather than require that they have logged in. Finally, the source code will be made available on GitHub and accessible at the end of this series in the following article. For now however, let's get started with working on the plugin.Read More…