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] => https://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] => https://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.
Comments