In this series, we've been taking a look at the
wp_remote_get WordPress HTTP API function in order to understand how it works, how we can use it, and the optional arguments that it accepts.
From here, we're able to write detailed requests; however, that's only half of it - there's also the response.
In the second article, we took a look at what a basic response would look like, how to evaluate it, and how to display it on the screen, but we didn't actually talk about the response in detail.
If you're looking to write more advanced requests and write more defensive code, then it's important to understand the data that's sent as a response. In this final article, we're going to do exactly that.
A Look at the Response
First, it's important to understand what I mean by writing defensive code: When writing software, we often have to work with the cases that a user may do something wrong, input may be set incorrectly, or data may be retrieved or received - such as in the case of a response - incorrectly.
To that end, we code defensively against those scenarios so that our software doesn't totally crash or bomb out while the user is using it. Instead, it fails gracefully and continues to run.
By knowing what exactly the function receives in response to its request, we know what data to look for, and then how to gracefully handle the case when it doesn't come back as we expect.
An Example Response
In order to set the stage for what to expect, let's take a look at an example response. Let's say you are to make a
GET request to a URL that will return a simple bit of text to you.
Generally speaking, you can expect to make more complicated requests where the response may be XML or JSON or something else; however, all of that information will be set in the
body index of the response array. So if you understand what to expect, then you understand how to handle it.
With that said, this is the response you could expect to receive from a simple request to a domain that returns nothing but plain text.
Array ( [headers] => Array ( [date] => Thu, 30 Sep 2010 15:16:36 GMT [server] => Apache [x-powered-by] => PHP/5.3.3 [x-server] => 10.90.6.243 [expires] => Thu, 30 Sep 2010 03:16:36 GMT [cache-control] => Array (  => no-store, no-cache, must-revalidate  => post-check=0, pre-check=0 ) [vary] => Accept-Encoding [content-length] => 1641 [connection] => close [content-type] => application/php ) [body] => 'A simple bit of text.' [response] => Array ( [code] => 200 [message] => OK ) [cookies] => Array() )
Nothing more than an array (or, really, an array of arrays). Nothing too bad, right?
Let's review each of the response elements in detail.
As you can tell from the response above, the headers are actually composed of another array that consists of other information.
Before looking at each piece of the information above, it's important to understand what exactly a header is. In short, headers give information about the request/response communication that exists between the client and the server.
There are a wide-variety of headers that can be sent back (many of which are beyond the scope of this article), but all of which help us to gain information not only about the request, but about the server with which we're communicating.
With that said, let's look at each header element in detail.
Clearly, this is an exceptionally easy element to understand: Simply put, this is the date and time that the message was sent. It obviously includes the day, date, and time all in Greenwich Mean Time which is a global standard of time.
The server element refers to the type of software on which the server is running. More often than not, you're likely to see Apache; however, there are other server applications available today such as IIS and the up and coming nginx.
X-Powered-By refers to the server software that's powering the transaction of the communication. In our case, we see PHP which simply means that our request was sent to a server running Apache and PHP.
This may not always be the case, though.
For example, you may end up communicating with a server running nginx and Python, or another type of server software running Ruby on Rails.
This particular response element refers to the IP address of the server to which the request is sent. I've rarely ever needed to know this particular information; however, if you end up getting an unexpected response despite the fact that all other information looks in order, it may help to know if the IP of the server matches what you'd expect for the domain to which the request is being sent.
Whenever a request is made and a response is sent, the response has a lifetime, so to speak.
More specifically, the response will be considered "stale" after a certain period of time. Obviously, the time at which the response is considered stale is when the response is said to have expired.
How long a response is considered non-stale is based on the configuration of the server, but the timestamp is of the same format as the date of the request.
Cache-control refers to the notion that a web browser (or some other caching mechanism that's in place between the client and the server) may or may not be able to use the first response as the response for future requests.
For example, if a server responds with
no-cache, then it means that the requesting machine's browser, server, or other proxy software or caching mechanism must treat each response as a new response. If, on the other hand,
no-cache is not specified, then the first response may be the only response that you're able to get (at least until the cache is set to expire).
This obviously consists of two indexes:
- The first index contains whether or not
no-cachehas been set
- The second index contains information if data has been cached. Simply put, if the
pre-checkinterval as expired, then a newer version of the data will be requested; otherwise, a cached version will be retrieved.
This particular aspect of caching is outside the scope of this series as much more could be written and explained; however, the definition above should be enough to help explain the headers that you're seeing.
This header value is similar to the Cache-Control header in that it tells requesting servers how to handle similar, subsequent requests.
Generally speaking, this will instruct the server whether or not a cache response can be used, or a fresh value must be retrieved. This is another element that can get excessively complicated, but in order to try to distill the explanation into something that's a bit more in scope for what we're discussing, the vary header element may also instruct the server on the various content types that the client can process.
So in the example above, we're instructing the server that our client is capable of being able to process encoded information.
Content-length is a simple concept with a single gotcha: First, it simply defines the length of the body of the response.
The thing is, it does so in 8-bit bytes. This means that the response is not provided in kilobytes, megabytes, or whatever form of data we're commonly used to seeing.
To that end, you may need to perform some conversion if you're looking to gather more rich information about the data that's returned.
The connection value specifies what type of connection the requesting browser would prefer. Above, we see that the value is defined as "close" meaning that once the response is sent, the connection can be closed.
However, there are other alternatives. For example, you may receive "keep-alive" which, obviously, wants to keep the connection alive for some amount of time.
Again, this is another example of something that would require its own article to fully discuss; however, this does give insight into the type of connection the server prefers which can help you in constructing future requests.
This is really only relevant to both
PUSH requests. In short, this defines the body type of the requests.
This can vary based on the data being sent. Sometimes it may be an encoded URL, sometimes it may be PHP, sometimes it may be something else. Regardless, this helps to make sure that we can check that the data coming back in the content is inline with what we expect given our request.
The body element actually contains the information returned from the server.
In our example from two articles ago, we received a JSON string from Twitter. In the example above, we're receiving a simple text string. Ultimately, the response could come back as some form of binary data that would need a level of de-serialization.
Whatever the case, it's up to us as the implementors of the request to know how to properly decode the response prior to displaying it to our users.
The response actually refers to the HTTP response code sent from the server back to the requesting client. If you're not familiar with HTTP status codes, then I recommend checking out HTTPStat.us for a really good reference.
In short, a response is made up of a numeric code and a text-based message to indicate the result of the request.
Code & Message
In the example above, you can see that we've received the '200' status code and the 'OK' message. The code and message pair should always be in-sync with one another.
This means that if you receive a '403' then you should also receive a 'Forbidden', or if you receive a '404' then you should receive a 'not found' message.
Personally, I've found these particular values to be important for diagnosing when problems have gone wrong with requests that I've made.
Finally, the cookie array refers to any information that's been sent across the wire based on the cookies that exist between the current client and server who are making the communication.
Depending on the nature of your request, this may or may not be empty - this varies too much on a case-by-case basis to provide any definitive guide. In short, if no cookies have been established between the two connections, then this will likely always be empty; otherwise, the data that comprises the cookie array will be specifically based on the cookies that exist between the two services.
Overall, there's a fair amount of data and it will vary from request to request based on what you're asking to receive and based on the server's response; however, the thing is that you now know what to expect and how to appropriately handle all the cases.
If worse comes to worse in your work, you can always use a debugger or simply place some debug statements, such as
var_dump in order to see what the server is returning so that you can gracefully handle the errors.
Later, we'll be revisiting the WordPress HTTP API to examine other methods such as
wp_remote_request so that we get a complete picture of the HTTP API.
Until then, this series will have hopefully provided you with as much in-depth coverage of
wp_remote_get to help not only improve your work but also to pique your curiosity about what else is possible when it comes to remote requests.