25

This should be soo simple but I have spent hours searching for the answer and am truly stuck. I am building a basic Laravel application and am using Guzzle to replace the CURL request I am making at the moment. All the CURL functions utilise raw JSON variables in the body.

I am trying to create a working Guzzle client but the server is respsonding with 'invalid request' and I am just wondering if something fishy is going on with the JSON I am posting. I am starting to wonder if you can not use raw JSON in the Guzzle POST request body? I know the headers are working as I am receiving a valid response from the server and I know the JSON is valid as it is currently working in a CURL request. So I am stuck :-(

Any help would be sooo greatly appreciated.

        $headers = array(
            'NETOAPI_KEY' => env('NETO_API_KEY'),
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
            'NETOAPI_ACTION' => 'GetOrder'
        );

    // JSON Data for API post
    $GetOrder = '{
        "Filter": {
            "OrderID": "N10139",
                "OutputSelector": [
                    "OrderStatus"
                ]
        }
    }';

    $client = new client();
    $res = $client->post(env('NETO_API_URL'), [ 'headers' => $headers ], [ 'body' => $GetOrder ]);

    return $res->getBody();
methode
  • 5,348
  • 2
  • 31
  • 42
Jason Hill
  • 293
  • 1
  • 3
  • 6
  • Hey guys. Thanks for the fast reply's. I ended up realising that I am a retard and had the headers and body in separate arrays. Changed this: [ 'headers' => $headers ], [ 'body' => $GetOrder ] To this: [ 'headers' => $headers, 'body' => $GetOrder ] – Jason Hill Jun 27 '15 at 11:04
  • Even so, you could have used the 'json' option, as demonstrated in my answer; it simplifies a few things. – Ja͢ck Jun 27 '15 at 11:13
  • Thanks Jack. It was a helpful answer but I have many calls with very long JSON queries and I don't want to have to convert them all into PHP to use the json function – Jason Hill Jun 27 '15 at 11:24
  • Not sure why you would want to build JSON strings by yourself, it seems rather counterproductive. – Ja͢ck Jun 27 '15 at 11:25

3 Answers3

35

You can send a regular array as JSON via the 'json' request option; this will also automatically set the right headers:

$headers = [
    'NETOAPI_KEY' => env('NETO_API_KEY'),
    'Accept' => 'application/json',
    'NETOAPI_ACTION' => 'GetOrder'
];

$GetOrder = [
    'Filter' => [
        'OrderID' => 'N10139',
        'OutputSelector' => ['OrderStatus'],
    ],
];

$client = new client();
$res = $client->post(env('NETO_API_URL'), [
    'headers' => $headers, 
    'json' => $GetOrder,
]);

Note that Guzzle applies json_encode() without any options behind the scenes; if you need any customisation, you're advised to do some of the work yourself

$res = $client->post(env('NETO_API_URL'), [
    'headers' => $headers + ['Content-Type' => 'application/json'],
    'body' => json_encode($getOrders, ...),
]);
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
14

Guzzle 7 Here

The below worked for me with raw json input

    $data = array(
       'customer' => '89090',
       'username' => 'app',
       'password' => 'pwd'  
    );
    $url = "http://someendpoint/API/Login";
    $client = new \GuzzleHttp\Client();
    $response = $client->post($url, [
        'headers' => ['Content-Type' => 'application/json', 'Accept' => 'application/json'],
        'body'    => json_encode($data)
    ]); 
    
    
    print_r(json_decode($response->getBody(), true));

For some reasons until I used the json_decode on the response, the output wasn't formatted.

Duke
  • 35,420
  • 13
  • 53
  • 70
0

You probably need to set the body mime type. This can be done easily using the setBody() method.

$request = $client->post(env('NETO_API_URL'), ['headers' => $headers]);
$request->setBody($GetOrder, 'application/json');
Jocke Med Kniven
  • 3,909
  • 1
  • 22
  • 23