无法 POST 使用 guzzle 与 Amadeus API 请求
Unable to POST request using guzzle with the Amadeus API
描述
我正在尝试将 Amadeus 自助服务 API 集成到 Laravel 环境中。我可以通过 GET
请求成功获取内容,但无法通过 POST
请求获取内容。我设置了异常来具体显示guzzle抛出的错误。
这是 api 参考,其中包含我想要 post 的数据和端点。
https://developers.amadeus.com/self-service/category/air/api-doc/flight-offers-search/api-reference
如何重现
这是我从 Client.php 调用并通过调用 POST 方法传递数据的方法。
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,
],
]);
}
调用POST方法后,我将'X-HTTP-Method-Override'作为'GET'传递,并将数据作为正文传递。
$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"],
],
],
],
],
],
]);
其他上下文
这是我在日志中发现的错误。
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)
请抽出时间看看,非常感谢帮助。
使用 Postman 或 Insomnia 等 HTTP 客户端时 POST 调用真的有效吗?
我注意到您正在传递一个 $options
数组并将其嵌套在 Guzzle 选项中。结果调用将如下所示:
$this->client->request('POST', $uri, [
['headers' => '...', 'body' => ['...']],
'headers' => ['...']
]);
那不行,你需要这样解压它们:
public function post($uri, array $options = []) {
$this->authenticate();
return $this->client->request('POST', $uri, [
...$options,
'headers' => [
'Authorization' => 'Bearer '.$this->access_token,
],
]);
}
注意点 ...
以解压缩选项数组。另请注意,您设置了 headers
键两次(一次在您的 post 方法定义中,一次在选项参数中),因此实际上只会使用一个(顺便说一句,您为什么要使用X-HTTP-Method-Override
header ?).
如果要在 POST 函数参数中传递所有 header 和 body 的另一种解决方案是:
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']
],
]);
}
如果不这样做,您可以尝试的另一件事是使用 Guzzle json
选项而不是 POST 请求的 body
。
当您探索任何 Amadeus 自助服务 API 时,我建议查看门户,因为它会帮助您了解如何进行 http 调用。
你的情况:
https://developers.amadeus.com/self-service/category/air/api-doc/flight-offers-search/api-reference
另一个帮助可能是查看编码示例:
描述
我正在尝试将 Amadeus 自助服务 API 集成到 Laravel 环境中。我可以通过 GET
请求成功获取内容,但无法通过 POST
请求获取内容。我设置了异常来具体显示guzzle抛出的错误。
这是 api 参考,其中包含我想要 post 的数据和端点。 https://developers.amadeus.com/self-service/category/air/api-doc/flight-offers-search/api-reference
如何重现
这是我从 Client.php 调用并通过调用 POST 方法传递数据的方法。
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,
],
]);
}
调用POST方法后,我将'X-HTTP-Method-Override'作为'GET'传递,并将数据作为正文传递。
$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"],
],
],
],
],
],
]);
其他上下文
这是我在日志中发现的错误。
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)
请抽出时间看看,非常感谢帮助。
使用 Postman 或 Insomnia 等 HTTP 客户端时 POST 调用真的有效吗?
我注意到您正在传递一个 $options
数组并将其嵌套在 Guzzle 选项中。结果调用将如下所示:
$this->client->request('POST', $uri, [
['headers' => '...', 'body' => ['...']],
'headers' => ['...']
]);
那不行,你需要这样解压它们:
public function post($uri, array $options = []) {
$this->authenticate();
return $this->client->request('POST', $uri, [
...$options,
'headers' => [
'Authorization' => 'Bearer '.$this->access_token,
],
]);
}
注意点 ...
以解压缩选项数组。另请注意,您设置了 headers
键两次(一次在您的 post 方法定义中,一次在选项参数中),因此实际上只会使用一个(顺便说一句,您为什么要使用X-HTTP-Method-Override
header ?).
如果要在 POST 函数参数中传递所有 header 和 body 的另一种解决方案是:
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']
],
]);
}
如果不这样做,您可以尝试的另一件事是使用 Guzzle json
选项而不是 POST 请求的 body
。
当您探索任何 Amadeus 自助服务 API 时,我建议查看门户,因为它会帮助您了解如何进行 http 调用。
你的情况: https://developers.amadeus.com/self-service/category/air/api-doc/flight-offers-search/api-reference
另一个帮助可能是查看编码示例: