1
votes

I'm trying to use Guzzle to consume a RESTful API. Reading the Guzzle documentation, I call methods like get and post to configure a request, then send to actually run an HTTP request.

$request = $client->post('http://httpbin.org/post', array(), array(
    'custom_field' => 'my custom value',
    'file_field'   => '@/path/to/file.xml'
));

$response = $request->send();

However in my case, it seems an HTTP request is being sent during the call to post without the fields. Here's my code

define('CUST_ID', 'blahblah');
define('API_KEY', 'verysecure');

// Construct the underlying Guzzle client
$oClient = new \GuzzleHttp\Client(
    ['base_url' =>
    ['http://api.postmates.com/{version}/', ['version' => 'v1']],
    'defaults' => [
        // HTTP Basic auth header, username is api key, password is blank
        'auth'    => [API_KEY, ''],
    ]]);
$oRq = $oClient->post(
    "customers/" . CUST_ID . "/delivery_quotes",
    [], 
    ['pickup_address'  => '232 E Manhattan Ave, Denver, CO 80203',
     'dropoff_address' => '4400 Midwest St, Denver, CO 80205']);

The request that goes out though (no POST params)

POST /v1/customers/blahblah/delivery_quotes HTTP/1.1
Host: api.postmates.com
Authorization: Basic verysecure==
User-Agent: Guzzle/5.2.0 curl/7.37.1 PHP/5.6.0
Content-Length: 0

and the response

HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
Date: Fri, 13 Feb 2015 07:32:16 GMT
Server: nginx/1.1.19
Content-Length: 205
Connection: keep-alive

{"kind": "error", "code": "invalid_params", "params": {"dropoff_address": "This field is required.", "pickup_address": "This field is required."}, "message": "The parameters of your request were invalid."}

So it looks like I'm authenticating, but not passing any post parameters. I tried using the setPostField method to set the POST fields with no luck. As I said it seems in that case an HTTP request is being sent before call setPostField, in either case an HTTP request is sent before I call send.

I've tried guzzlehttp/guzzle 5.2.0 and 5.0.0.

1

1 Answers

4
votes

Wow, looks like I was looking at 2 pieces of documentation, one for the newer GuzzleHttp\Client, one for the older Guzzle\Http\Client. The big difference with the new library is you need to call createRequest if you want to defer invocation of the HTTP request.

Working code under the new library

define('CUST_ID', 'blahblah');
define('API_KEY', 'verysecure');

// Construct the underlying Guzzle client
$oClient = new GuzzleHttp\Client(
    ['base_url' =>
    ['http://api.postmates.com/{version}/', ['version' => 'v1']],
    'defaults' => [
        // HTTP Basic auth header, username is api key, password is blank
        'auth'    => [API_KEY, ''],
    ]]);

// Create the request
$oRq = $oClient->createRequest(
    'POST',
    "customers/" . CUST_ID . "/delivery_quotes",
    [ 'body' =>
        ['pickup_address'  => '232 E Manhattan Ave, Denver, CO 80203',
         'dropoff_address' => '4400 Midwest St, Denver, CO 80205']]);

// Send the request
$oRsp = $oClient->send($oRq);