Working with HTTP APIs in WordPress

There are APIs everywhere, and you might not realize it but they aren’t a single thing. “API” is a general term for any interface between a piece of technology and the outside world, and WordPress has tons of them internal to its working: You save site-level data with the Options API; plugins use the Plugin API to work; and I could easily go on.

But more often then not, when you hear people in the general public talking about APIs, they mean a very particular type: an API that is accessed over the internet and used to make data available to anyone with an internet connection. That’s what most people mean when they say things like “the Flickr API,” “Twitter’s locking down their API,” and “man, I really hate the Facebook API.” Or, closer to home, when they discuss the long-standing WordPress XML-RPC API, or the JSON API which we’ll get some day. These are the WordPress HTTP APIs.

So this week we’ll talk about how you can use HTTP APIs in WordPress itself. Lets say that you wanted to pull in your most recent tweets and save them, or make your WordPress site publish to Facebook when you publish a new post. We won’t specifically implement either of those this week — those APIs specifically have some complex authorization flows that are a bit more advanced — but we will cover what all those things mean.

A Quick Introduction to the Internet

The internet works through Hypertext Transport Protocol or HTTP. You don’t need to understand HTTP to do most of your work as a web publisher, browser, or even developer; but to be very comfortable with HTTP APIs, you do need to understand a little bit about HTTP.

Different HTTP methods are used for different goals.

Primarily, you need to understand that there are different methods of HTTP, and they’re used for different goals.

There are, all told, eight HTTP methods, but for a basic ability to productively work with the WordPress HTTP API, we really just need to know about three:

  • GET — GET is probably the most common and familiar HTTP method for people. It’s essentially what your browser is doing for you when you visit a page like https://wpshout.com: your browser sends a GET request. GET requests are how you retrieve an HTTP resource, including its main body. It’s also good to know that generally GET requests are free of side-effects; that is, a server shouldn’t be destroying or changing things in response to GET requests. (There’s no guarantee that that’s true — HTTP doesn’t stop you being dumb and making GET requests delete your database — but it’s generally assumed.)
  • HEAD — I call out HEAD not because it’s so useful, but because it does have it own convenience methods in WordPress’s HTTP API. Essentially HEAD is a GET request where you don’t want the actual body of the resource. If you were just collecting metadata about websites, for example, you could just make a HEAD request to https://wpshout.com and you’d get an answer like you would for a GET, but without the body.
  • POST — The most common method for HTTP requests which are supposed to have side effects — make the server save data, do an action, etc. — is the POST request. Where a GET request is just a simple “can I have that?” request, a POST is a more elaborate “you wanted this information and I’m providing it, now please can I have that?” If you fill out a form, post a new tweet, or check-in at a location, some layer of software somewhere is probably making a POST request for you.

There are other methods that matter for most people: PUT & PATCH are used in slightly different ways to change data you make with a POST; DELETE does what you’d guess. But on the whole, GET and POST are the two you must understand.

The WordPress APIs for HTTP Requests

The WordPress HTTP APIs are essentially of two classes: those that make requests and those that help you to make sense of the responses you get back. As you’d guess, those that make requests are used first, and then you’ll use the response handlers with the results of the requesting functions.

The Functions to Actually Make HTTP Requests

The requesting functions let you make GET and POST and HEAD, and even PUT and DELETE, requests. And they’re pretty simple to guess: wp_remote_get() helps you do a GET request, wp_remote_post() is for POST, and as you’d guess wp_remote_head() is for your HEAD needs. All of those are basically just slightly more convenient uses of wp_remote_request(), which itself can make every kind of request, even those not specified with a convenience function.

And all four of these functions have the same signature: they take a URL as the first argument, and that old-time WordPress favorite—an array of $args which you can skip or simplify—as the second argument. So to just get the response for WPShout itself, as we already mentioned, you can do either of these:

$response = wp_remote_get('https://wpshout.com');
// is equivalent to
$response = wp_remote_request(
    'https://wpshout.com',
    array('method' => 'GET')
);

There are a number of other useful things that can go into the $args array. 'user-agent' can be set to make your HTTP request look like it came from “SUPER COOL HTTP REQUESTOR” (or a browser, maybe) rather than “WordPress/4.1; https://wpshout.com”. 'timeout' lets you specify how long you want to let the request take before it’s given up on. 'redirect' lets you specify how many, if any, redirects you’ll accept. 'blocking' says whether or not you want everything else in your script’s execution to wait on your request. 'headers' lets you set an array of pairs of keys and values you want to end up in the HTTP request header itself. There are a few more I’ve never had cause to use, and they’re reasonably well-explained in the Codex.

Handling the HTTP Response

What you get back from the wp_remote_request family of functions is a response. It’s a structured PHP array with a lot of data in it, and you can actually just parse it out yourself and find everything that’s in it. Somewhere in there is likely the part you’re specifically looking for, so a little bit of var_dumping or print_ring will likely allow you to find what you want.

Use some helper functions to get just what you want.

Or, more commonly and helpfully, you can use some little helper functions that WordPress provides to get you just what you want without needing to remember the (kind of strange) structure of WordPress’s HTTP responses. In all cases, you just want to pass in your response as the sole parameter to the functions. What those functions are and what they do:

  • wp_remote_retrieve_body — Gives you the actual body of the response. In the case of the request we made above to this site, you’d basically get all the HTML that your browser renders.
  • wp_remote_retrieve_headers — Note the final “s”; this returns a PHP array of all the HTTP Headers the response had in it.
  • wp_remote_retrieve_header makes me a bit of liar: it requires a second function parameter. By specifying the HTTP header you want from the response, it gives you just that. It’s essentially a step saved from using wp_remote_retrieve_headers.
  • wp_remote_retrieve_response_code — Will give you the numeric HTTP status code for the response — like 404 or 200 or 501. If you succeeded it’ll probably be in the 200s, if you did something wrong it’s in the 400s, if the server’s messing up it should be in the 500s.
  • wp_remote_retrieve_response_message is useful if you find the numbers daunting. It’ll translate that number into a text version, like “Unauthorized” instead of 401.

Why Not Just Use…?

You don’t have to use the WordPress HTTP API to make requests, but you totally can.

One final thing to consider is that you don’t have to use the WordPress HTTP API to make requests. After all, PHP has a number of ways to make similar requests, so why not just use those?

The very short answer is “you totally can.” The slightly longer answer continues “but you probably do want the solution that you can rely on to work wherever WordPress does, in the way WordPress does.” WordPress has seen, gotten bug reports from, and been battle-tested against a massive number of servers, hosting configurations, and meddling hosts. As a WordPress developer, take advantage of that. Plus, PHP’s CURL library — which WordPress usually uses under the hood — is often complained about. And you really shouldn’t just go with a file_get_contents() and your fingers crossed, either. That’s why you probably want to stick with the WordPress way instead of something else.

What We’ve Learned

What I hope you’ve gotten from this is sound sense of what the WordPress HTTP API is used for, how you’d use it, and some of what you can do with it. Though our example was just getting the homepage of our site, you’d be much more likely to use this concept to do something like get a JSON payload from Twitter, and parse it into something pretty you’ll store or display on the user’s screen. I hope that with the theoretical and practical knowledge here, you’re ready to do something like that. Happy hacking!

Image credit: Ryan McGuire


3 Responses

Pingbacks