I am trying to make a http client request in Laravel. I have tried using guzzle directly and it works, but when doing it through "API around the Guzzle HTTP client" in laravel, I always get a 400.
I can’t find where the error is, since it seems to be correctly.
I give the example of the two cases:
$method = ‘post’, and route and $headers are the same too.
Guzzle (200 success):
$client = new GuzzleHttpClient();
$response = $client->request($method, $this->BASEURL . $endpoint, [
'body' => '{"name":"testName"}',
'headers' => $headers,
]);
Laravel http Client (400 bad request):
$response = Http::withHeaders($headers)->withBody('{"name":"testName"}', 'application/json')->{$method}($this->BASEURL . $endpoint);
EDIT
Example from AirbnbAPI using guzzle:
<?php
require_once('vendor/autoload.php');
$client = new GuzzleHttpClient();
$response = $client->request('POST', 'https://api.airbnb.com/v2/listings', [
'body' => '{"name":"erer"}',
'headers' => [
'X-Airbnb-API-Key' => 'XXXXXXXX',
'X-Airbnb-OAuth-Token' => 'XXXXXX',
'X-Airbnb-Req-Api-Version' => '2022.12.31',
'accept' => 'application/json',
'content-type' => 'application/json',
],
]);
echo $response->getBody();
3
Answers
You’re using the
HTTP
package wrong. The way we useHTTP
package in Laravel is by utilizing theGuzzleHTTP
i.e.use GuzzleHttpPsr7Utils;
for example the code can be something like this:You can learn more about GuzzleHTTP package on Laravel official website documentation
You could pass in the json body directly when calling the method as a second argument:
By default data will be sent using the application/json content type.
If your
$headers
array has a "content-type" key that is not cased asContent-Type
, then the issue may be that you’re sending over multiple content-type headers.For example, if your
$headers
array has acontent-type
key, then with the call towithHeaders()
, you’re setting thecontent-type
header.The next call to
withBody()
will then set theContent-Type
header toapplication/json
.Since the header names are keys in an array, and they are not the same (array keys are case sensitive), the headers array will end up with both a
content-type
header and aContent-Type
header, and both will be sent in the request.You either need to remove the
content-type
entry from your$headers
variable, or you need to ensure it is cased asContent-Type
so the Http client will overwrite it properly.