Wern Ancheta

Adventures in Web Development.

Making HTTP Requests With Guzzle

| Comments

Most PHP applications today includes the ability to integrate with different web services such as Facebook, Twitter, Google, and other API’s. Thus the need for a library to ease the process of making HTTP requests to other servers. Most API’s already comes with their own clients for selected programming languages. These clients makes the interaction with their API’s easier. But oher services doesn’t offere any clients at all. This is where Guzzle comes in, a PHP library that allows you to easily make HTTP requests. In this tutorial, I’ll be walking you through this library.

Installation

You can install Guzzle through Composer by executing the following command.

1
composer require guzzlehttp/guzzle:~6.0

Usage

You can start using Guzzle by including the vendor autoload file then use the Client class in the GuzzleHttp namespace.

1
2
3
4
5
<?php
require_once 'vendor/autoload.php';

use GuzzleHttp\Client;
?>

From there, you can create a new client. This accepts an array of arguments. The most important one is the base_uri, which is the base URL that will be used for each of the requests that you will make with this client. In the example below, the base URI is that of the Pokemon API, an API which allows you to get any data about Pokemon.

1
2
3
<?php
$client = new Client(['base_uri' => 'http://pokeapi.co/api/v1/']);
?>

To make an actual request to an endpoint, you can use the get method to make a GET HTTP request. To extract the response body, you have to call the getBody method in the response that was returned. Most API’s today returns a JSON string as their response. The Pokemon API is no exception. So you need to use the json_decode method and pass in the data. You can pass in true as the second argument to convert it to an array.

1
2
3
4
5
6
7
8
<?php
$response = $client->get('pokedex/1');
$data = $response->getBody();
$data = json_decode($data, true);
?>
<pre>
<?php print_r($data); ?>
</pre>

Here’s the output that you get when accessing the file from the browser. From this data, we know that the pokedex/1 endpoint returns all the pokemon that are currently existing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Array
(
    [created] => 2013-11-09T15:14:48.957604
    [modified] => 2013-11-09T15:14:48.957565
    [name] => national
    [pokemon] => Array
        (
            [0] => Array
                (
                    [name] => rattata
                    [resource_uri] => api/v1/pokemon/19/
                )

            [1] => Array
                (
                    [name] => charmander
                    [resource_uri] => api/v1/pokemon/4/
                )

            [2] => Array
                (
                    [name] => charmeleon
                    [resource_uri] => api/v1/pokemon/5/
                )

            [3] => Array
                (
                    [name] => wartortle
                    [resource_uri] => api/v1/pokemon/8/
                )

            [4] => Array
                (
                    [name] => blastoise
                    [resource_uri] => api/v1/pokemon/9/
                )

            [5] => Array
                (
                    [name] => caterpie
                    [resource_uri] => api/v1/pokemon/10/
                )

            [6] => Array
                (
                    [name] => metapod
                    [resource_uri] => api/v1/pokemon/11/
                )

            [7] => Array
                (
                    [name] => butterfree
                    [resource_uri] => api/v1/pokemon/12/
                )

            [8] => Array
                (
                    [name] => spearow
                    [resource_uri] => api/v1/pokemon/21/
                )

            [9] => Array
                (
                    [name] => kakuna
                    [resource_uri] => api/v1/pokemon/14/
                )

            [10] => Array
                (
                    [name] => beedrill
                    [resource_uri] => api/v1/pokemon/15/
                )
...

Note that it’s not only get method that you can do with Guzzle. Each HTTP methods have their equivalent method in Guzzle. So post, put and delete are all valid method names.

Before moving on, here’s another example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
$response = $client->get('pokemon/150');
$data = $response->getBody();
$data = json_decode($data, true);

$moves = array_filter($data['moves'], function($move){
    return $move['learn_type'] == 'level up';
});

$description_response = $client->get(str_replace('/api/v1/', '', $data['descriptions'][0]['resource_uri']));
$description_data = $description_response->getBody();
$description_data = json_decode($description_data, true);
?>
<div>
    <img src="<?= 'http://pokeapi.co/media/img/' . $data['pkdx_id'] . '.png' ?>" alt="<?= $data['name'] ?>">
    <h4><?= $data['name'] ?></h4>
    <p>
        <?= $description_data['description']; ?>
    </p>
    <div>
        <strong>Moves</strong>
        <ul>            
        <?php
        foreach($moves as $move){
        ?>
        <li>
            <?= $move['name']; ?>
        </li>
        <?php
        }
        ?>
        </ul>
    </div>
</div>

In the code above, 2 GET request were used to get all the data that is needed for the final output. First, the pokemon endpoint is used to get the details of a specific pokemon. Second is the request for getting the description of the pokemon. In order to extract the moves, the array_filter function is used. The condition is to select only moves that have been learned through level up. In order to get the endpoint for getting the description, the str_replace function is used to replace a part of the base uri in the resource uri that was returned. Since the resource uri already has the /api/v1/ in the beginning. Guzzle would end up making a request to the following URL if that string isn’t replace with an empty one.

1
http://pokeapi.co/api/v1//api/v1/description/150

The output is going to look like this.

mewtwo

Finally let’s take a look at how to do a POST request with Guzzle. For that let’s try to submit a post to Facebook using Facebook API. To do that, declare a new client using the https://graph.facebook.com/ as the base_uri. Posting to facebook requires the access_token, message and an optional link. Call the post method and pass in me/feed as the first argument. This is the endpoint for posting to facebook. The second argumment is an array containing the data that you want to submit. In Guzzle, the data should be contained within the query item. You can then call getBody on the response to get the response body. This should return the ID of the post that was created.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$client = new Client(['base_uri' => 'https://graph.facebook.com/']);

$post_data = array(
    'access_token' => 'YOUR-FACEBOOK-ACCESS-TOKEN',
    'message' => 'testing',
    'link' => 'http://wern-ancheta.com/'
);


$res = $client->post('me/feed', array(
    'query' => $post_data
));

$response_body = $res->getBody();
$response_body = json_decode($response_body, true);
?>

Conclusion

That’s it! In This tutorial, you’ve learned how to make HTTP requests with the Guzzle library. There’s so much more you can do with Guzzle, so be sure to check out their official docs if you want to learn more.

Comments