Description
I am trying to integrate Amadeus Self-Service API within the Laravel Environment. I am successfully able to get content by GET
request, but I am not able to get content by the POST
request. I have set the exceptions to display the errors thrown by the guzzle in specific.
Here is the api reference, which has the data and the endpoint which I want to post to. https://developers.amadeus.com/self-service/category/air/api-doc/flight-offers-search/api-reference
How to reproduce
This is the method which I call from my Client.php and pass the data through by calling the POST method.
public function __construct() {
throw_if(static::$instance, 'There should be only one instance of this class');
static::$instance = $this;
$this->client = new Client([
'base_uri' => 'https://test.api.amadeus.com/',
]);
}
public function get($uri, array $options = []) {
$this->authenticate();
return $this->client->request('GET', $uri, [
$options,
'headers' => [
'Authorization' => 'Bearer '.$this->access_token,
],
]);
}
public function post($uri, array $options = []) {
$this->authenticate();
return $this->client->request('POST', $uri, [
$options,
'headers' => [
'Authorization' => 'Bearer '.$this->access_token,
],
]);
}
After calling the POST method, I pass the 'X-HTTP-Method-Override' as 'GET', and pass the data as body.
$requests_response = $client->post('v2/shopping/flight-offers', [
'headers' => [
'X-HTTP-Method-Override' => 'GET',
],
'body' => [
[
"currencyCode" => "USD",
"originDestinations" => [
[
"id" => "1",
"originLocationCode" => "RIO",
"destinationLocationCode" => "MAD",
"departureDateTimeRange" => [
"date" => "2022-11-01",
"time" => "10:00:00",
],
],
[
"id" => "2",
"originLocationCode" => "MAD",
"destinationLocationCode" => "RIO",
"departureDateTimeRange" => [
"date" => "2022-11-05",
"time" => "17:00:00",
],
],
],
"travelers" => [
["id" => "1", "travelerType" => "ADULT"],
["id" => "2", "travelerType" => "CHILD"],
],
"sources" => ["GDS"],
"searchCriteria" => [
"maxFlightOffers" => 2,
"flightFilters" => [
"cabinRestrictions" => [
[
"cabin" => "BUSINESS",
"coverage" => "MOST_SEGMENTS",
"originDestinationIds" => ["1"],
],
],
"carrierRestrictions" => [
"excludedCarrierCodes" => ["AA", "TP", "AZ"],
],
],
],
],
],
]);
Additional context
Here is the error, which I caught in the log.
local.ERROR: Guzzle error {"response":{"GuzzleHttp\\Psr7\\Stream":"
{
\"errors\": [
{
\"code\": 38189,
\"title\": \"Internal error\",
\"detail\": \"An internal error occurred, please contact your administrator\",
\"status\": 500
}
]
}
"}}
local.ERROR: Server error: POST https://test.api.amadeus.com/v2/shopping/flight-offers resulted in a 500 Internal Server Error response:
{
"errors": [
"code": 38189,
(truncated...)
"exception":"[object] (GuzzleHttp\\Exception\\ServerException(code: 500): Server error: POST https://test.api.amadeus.com/v2/shopping/flight-offers resulted in a 500 Internal Server Error response:
"errors": [
"code": 38189,
(truncated...)
at C:\\xampp\\htdocs\\Application\\vendor\\guzzlehttp\\guzzle\\src\\Exception\\RequestException.php:113)
Please spare some time to have a look, help is really appreciated.
Do the POST calls actually work using a HTTP client such as Postman or Insomnia ?
I am noticing is that you are passing an array of $options
and are nesting it inside the Guzzle options. The resulting call will look something like this:
$this->client->request('POST', $uri, [
['headers' => '...', 'body' => ['...']],
'headers' => ['...']
]);
That won't work, you are going to need to unpack them this way:
public function post($uri, array $options = []) {
$this->authenticate();
return $this->client->request('POST', $uri, [
...$options,
'headers' => [
'Authorization' => 'Bearer '.$this->access_token,
],
]);
}
Notice the dots ...
to unpack the options array. Also notice that you are setting the headers
key twice (once in your post method definition and once in the options parameter), so only one will actually be used (by the way why exactly are you using the X-HTTP-Method-Override
header ?).
Another solution if you want to pass all header and body in the POST function parameters is this:
public function post($uri, array $options = []) {
$this->authenticate();
return $this->client->request('POST', $uri, [
'json' => $options['json'], // I would suggest 'json' because it looks like the API is looking for a JSON body, if that doesn't work go with 'body'
'headers' => [
'Authorization' => 'Bearer '.$this->access_token,
...$options['headers']
],
]);
}
Another thing you might try if this doesn't do it is using the Guzzle json
option instead of body
for the POST request.