简体   繁体   中英

Why do I get a 400 Bad Request error from api

I am trying to call a shiplogic API (based in AWS), but I get 400 Bad Request error.

I have tried various ways to request response from the AWS API such as S3, I have tried creating my own signature for a cURL request, and now I am trying this code.

$host = "api.shiplogic.com";
$accessKey = 'AKIA55D****';
$secretKey = 'cx0WDJLNj1Bmn2**';
$requestUrl = 'https://api.shiplogic.com';
$uri = '/tracking/shipments';
$httpRequestMethod = 'GET';
$data = '{"tracking_reference": "M3RPH"}';

require 'AWS/aws-autoloader.php';;
use Aws\Signature\SignatureV4;
use Aws\Credentials\Credentials;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Psr\Http\Client\ClientInterface;

$signature = new SignatureV4('execute-api', 'af-south-1');
$credentials = new Credentials($accessKey, $secretKey);
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri, ["content-type"=>"application/json"], $data);
$client = new Client([$requestUrl, 'timeout' => 30]);
$sr = $signature->signRequest($psr7Request, $credentials);
$response = $client->send($sr);
var_dump($response);

The short error is: PHP Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: GET https://api.shiplogic.com/tracking/shipments resulted in a 400 Bad Request response: Invalid or incomplete input

The full error is:

PHP Fatal error:  Uncaught GuzzleHttp\Exception\ClientException: Client error: `GET https://api.shiplogic.com/tracking/shipments` resulted in a `400 Bad Request` response:
Invalid or incomplete input

in /home/path/myurl.com/path/AWS/GuzzleHttp/Exception/RequestException.php:113

Stack trace:
#0 /home/path/myurl.com/path/AWS/GuzzleHttp/Middleware.php(65): GuzzleHttp\Exception\RequestException::create()
#1 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(204): GuzzleHttp\Middleware::GuzzleHttp\{closure}()
#2 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(153): GuzzleHttp\Promise\Promise::callHandler()
#3 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/TaskQueue.php(48): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
#4 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(248): GuzzleHttp\Promise\TaskQueue->run()
#5 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(224): GuzzleHttp\Promise\Promise->invokeWaitFn()
#6 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(269): GuzzleHttp\Promise\Promise->waitIfPending()
#7 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(226): GuzzleHttp\Promise\Promise->invokeWaitList()
#8 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#9 /home/path/myurl.com/path/AWS/GuzzleHttp/Client.php(129): GuzzleHttp\Promise\Promise->wait()
#10 /home/path/myurl.com/path/apiSign.php(22): GuzzleHttp\Client->send()
#11 {main}
thrown in /home/path/myurl.com/path/AWS/GuzzleHttp/Exception/RequestException.php on line 113

EDIT:

Screenshot of cURL created by Postman

在此处输入图像描述

EDIT 2

Response from using $psr7Request = new Request($httpRequestMethod, $requestUrl.$uri.'?tracking_reference=M3RPH');

GuzzleHttp\Psr7\Response Object
(
[reasonPhrase:GuzzleHttp\Psr7\Response:private] => OK
[statusCode:GuzzleHttp\Psr7\Response:private] => 200
[headers:GuzzleHttp\Psr7\Response:private] => Array
    (
        [Date] => Array
            (
                [0] => Sat, 30 Jul 2022 09:08:57 GMT
            )

        [Content-Type] => Array
            (
                [0] => application/json
            )

        [Content-Length] => Array
            (
                [0] => 743
            )

        [Connection] => Array
            (
                [0] => keep-alive
            )

        [Ship-Logic-Request-Id] => Array
            (
                [0] => e78565f7-3a63-4831-8cdd-f4c720c13f06
            )

        [Apigw-Requestid] => Array
            (
                [0] => WEs-jjI6ifMEPcQ=
            )

    )

[headerNames:GuzzleHttp\Psr7\Response:private] => Array
    (
        [date] => Date
        [content-type] => Content-Type
        [content-length] => Content-Length
        [connection] => Connection
        [ship-logic-request-id] => Ship-Logic-Request-Id
        [apigw-requestid] => Apigw-Requestid
    )

[protocol:GuzzleHttp\Psr7\Response:private] => 1.1
[stream:GuzzleHttp\Psr7\Response:private] => GuzzleHttp\Psr7\Stream  Object
    (
        [stream:GuzzleHttp\Psr7\Stream:private] => Resource id #45
        [size:GuzzleHttp\Psr7\Stream:private] => 
        [seekable:GuzzleHttp\Psr7\Stream:private] => 1
        [readable:GuzzleHttp\Psr7\Stream:private] => 1
        [writable:GuzzleHttp\Psr7\Stream:private] => 1
        [uri:GuzzleHttp\Psr7\Stream:private] => php://temp
        [customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
            (
            )

    )

)

POSTMAN response from the same call:

{
"shipments": [
    {
        "provider_id": 10,
        "shipment_id": 14135,
        "short_tracking_reference": "G9G",
        "status": "cancelled",
        "shipment_time_created": "2021-05-21T12:12:03.365338Z",
        "shipment_time_modified": "2022-05-31T14:00:34.375688Z",
        "shipment_collected_date": null,
        "shipment_delivered_date": null,
        "collection_from": "uAfrica.com",
        "delivery_to": "",
        "collection_hub": "Gauteng",
        "delivery_hub": "Gauteng",
        "service_level_code": "ECO",
        "tracking_events": [
            {
                "id": 1940829,
                "parcel_id": 0,
                "date": "2021-11-22T14:21:00.000529Z",
                "status": "delivered",
                "source": "corneladmin",
                "message": ""
            },
            {
                "id": 1940828,
                "parcel_id": 0,
                "date": "2021-11-22T14:20:59.925068Z",
                "status": "collected",
                "source": "corneladmin",
                "message": ""
            },
            {
                "id": 1940812,
                "parcel_id": 0,
                "date": "2021-11-22T14:20:45.323472Z",
                "status": "delivered",
                "source": "corneladmin",
                "message": ""
            },
            {
                "id": 1940811,
                "parcel_id": 0,
                "date": "2021-11-22T14:20:45.317556Z",
                "status": "collected",
                "source": "corneladmin",
                "message": ""
            },
            {
                "id": 1940755,
                "parcel_id": 0,
                "date": "2021-11-22T14:19:12.481537Z",
                "status": "delivered",
                "source": "corneladmin",
                "message": ""
            },
            {
                "id": 1940754,
                "parcel_id": 0,
                "date": "2021-11-22T14:19:12.462331Z",
                "status": "collected",
                "source": "corneladmin",
                "message": ""
            },
            {
                "id": 1940726,
                "parcel_id": 0,
                "date": "2021-11-22T14:18:37.02554Z",
                "status": "delivered",
                "source": "sandbox-admin",
                "lat": -25.806655,
                "lng": 28.334732,
                "message": "POD files captured"
            },
            {
                "id": 1940725,
                "parcel_id": 0,
                "date": "2021-11-22T14:18:37.011858Z",
                "status": "collected",
                "source": "sandbox-admin",
                "message": ""
            },
            {
                "id": 1940713,
                "parcel_id": 0,
                "date": "2021-11-22T14:18:20.002241Z",
                "status": "delivered",
                "source": "sandbox-admin",
                "lat": -25.806655,
                "lng": 28.334732,
                "message": "POD files captured"
            },
            {
                "id": 1940712,
                "parcel_id": 0,
                "date": "2021-11-22T14:18:19.995663Z",
                "status": "collected",
                "source": "sandbox-admin",
                "message": ""
            },
            {
                "id": 332828,
                "parcel_id": 0,
                "date": "2021-06-04T09:30:36.170053Z",
                "status": "cancelled",
                "source": "sandbox-admin",
                "message": ""
            },
            {
                "id": 254076,
                "parcel_id": 0,
                "date": "2021-05-21T12:12:03.846219Z",
                "status": "submitted",
                "source": "sandbox-admin",
                "message": ""
            }
        ]
    }
]
} 

The documentation says that you need to pass the tracking_reference parameter on the query string (just as you did with Postman):

https://api.shiplogic.com/tracking/shipments?tracking_reference=G9G

But that's not what your code does:

$data = '{"tracking_reference": "M3RPH"}';
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri, ["content-type"=>"application/json"], $data)

The exception message clearly shows that the parameter is missing from the URL:

`GET https://api.shiplogic.com/tracking/shipments` resulted in a `400 Bad Request` response

You should do something like this instead:

$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri.'?tracking_reference=M3RPH');

I was facing the same issue while using Creatio API. Just like your case the API was working in Postman but not when using Curl in PHP. Sometimes postman sends some extra headers in the HTTP request. In my case postman was sending a cookie header anonymously. So to check this: Navigate to the code section of Postman which appears on the right side of the application. Choose PHP as a programming language, it will show you the complete Curl request for your case.

在此处输入图像描述 在此处输入图像描述

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM