3

I have built an API and an application that uses that API. Everything was working but now, for some reason, I get a 400 Bad Request response. I am not sure if I changed something in the code so I wanted to double check it was correct.

So my API call is this

$client = new GuzzleHttp\Client();

$jsonData = json_encode($data);

$req = $client->request('POST', 'https://someurl.com/api/v1/createProject', [
    'body' => $jsonData,
    'headers' => [
        'Content-Type' => 'application/json',
        'Content-Length' => strlen($jsonData),
    ]
]);

$output = $req->getBody()->getContents();

The API has a route set up correctly which uses post. The function it calls is correct, and I have changed it for testing to simply return

return response()->json(["Success", 200]);

When I test the API out within Postman, I can see that Success is returned. When I test the API within the other application I have built, I dont even see a POST request within the console, I am just displayed a Laravel error 400 Bad Request.

What could be the cause of this issue?

Thanks

Update

I have changed the request to this

$data= json_encode($data);

$req = $client->post('https://someurl.com/api/v1/createProject', [
    'body' => $data
]);

If I output $data after it has been encoded, I get something like this

{
    "projectName":"New Project",
    "clientName":"Test Client",
}

Within the controller function of the API that is being called, I simply do

return response()->json(['name' => $request->input('clientName')]);

The 400 error has now gone, but I now get null returned to me

{#326 ▼
  +"name": null
}

Request is being injected into the function as it should be. Should I be returning the data in a different way?

Thanks

katie hudson
  • 2,765
  • 13
  • 50
  • 93

2 Answers2

1

Probably you did $ composer update and Guzzle updated.

So if you are using newest Guzzle (guzzlehttp/guzzle (6.2.2)) you do POST request:

$client = new GuzzleHttp\Client();

$data = ['name' => 'Agent Smith'];

$response = $client->post('http://example.dev/neo', [
    'json' => $data
]);

You do not need to specify headers.

To read response you do following:

$json_response = json_decode($response->getBody());

My full example (in routes file web.php routes.php)

Route::get('smith', function () {
    $client = new GuzzleHttp\Client();

    $data = ['name' => 'Agent Smith']; 

    $response = $client->post('http://example.dev/neo', [
        'json' => $data,
    ]);

    $code = $response->getStatusCode();
    $result = json_decode($response->getBody());

    dd($code, $result);
});

    Route::post('neo', function (\Illuminate\Http\Request $request) {
        return response()->json(['name' => $request->input('name')]);
    });

or you could use following (shortened), but code above is "shorter"

$json_data = json_encode(['name' => 'Agent Smith']);

$response = $client->post('http://example.dev/neo', [
    'body' => $json_data,
    'headers' => [
        'Content-Type' => 'application/json',
        'Content-Length' => strlen($json_data),
    ]
]);

note: If you are running PHP5.6, change always_populate_raw_post_data to -1 (or uncomment the line) in php.ini and restart your server. Read more here.

Community
  • 1
  • 1
Kyslik
  • 8,217
  • 5
  • 54
  • 87
  • @kate_hudson see update, its working as expected, I removed pre-update full example and replaced it with new one. Read answer from scratch. – Kyslik Oct 08 '16 at 22:42
0

In my case I was using public IP address in BASE_URL while I should have been using the private IP. From mac you can get your IP by going into system preferences -> network.

This is with Android + Laravel (API)

DragonFire
  • 3,722
  • 2
  • 38
  • 51