I need to do a post call to a web service, with "authorization" field in the header, but I always get 500 Internal Server Error from the server.
The strange thing is if I do the same call with Postman I get the result.
I thought that my guzzle call is wrong.
This is the code:
$client = new Client([
'verify' => false
]);
try {
$res = $client->post(
$base_uri . $uri, [
'headers' => [
'content-type' => 'application/json',
'authorization' => $login['token'],
],
'form_params' => []
]
);
echo 'OK';
return json_decode($res->getBody(), true);
} catch (GuzzleHttp\Exception\ClientException $e) {
echo 'ClientException';
} catch (Exception $exc) {
echo 'Exception';
}
This catches the "Exception" exception.
I attach the image of postman call that does not get the error.
I checked:
the uris are the same;
the authorization parameters are the same;
the body in postman is empty.
Related
I'm setting up Guzzle as my Laravel 6's HTTP Client in my project. It was perfectly working and giving responses on every API hit. But suddenly it returns "Call to a member function getStatusCode() on null" error.
I've tried using Postman and curl to hit the API, and they return the right response when Guzzle not.
Instead of returning response, the print_r for RequestException response's return null.
I've tried to debug the REST API to test where the request go when hitting it using Guzzle, and the request didn't even hit to the destination function.
Here's my Guzzle code:
class ApiCallback
{
public static function request($method, $uri, $params = [], $useAccessToken = true){
$client = new \GuzzleHttp\Client();
$response = null;
$jsonObj = null;
try{
if($useAccessToken){
$response = $client->request(
strtoupper($method),
$uri,
[
"headers" =>[
'Accept' => '*/*',
"Authorization" => "Bearer ".Session::get('access_token'),
'Content-Type' => 'application/json',
'User-Agent' => 'saranaku-'.Session::get('id'),
'Content-Length' => '0',
'Accept-Encoding' => 'gzip, deflate, br',
'Connection' => 'keep-alive'
]
,
"body" => \json_encode(
$params
)
]
);
}else{
$response = $client->request(
strtoupper($method),
$uri,
[
"headers" =>[
'Accept' => '*/*',
'Content-Type' => 'application/json',
'User-Agent' => "saranaku-guest",
'Content-Length' => '0',
'Accept-Encoding' => 'gzip, deflate, br',
'Connection' => 'keep-alive'
]
,
"body" => \json_encode(
$params
)
]
);
}
$jsonObj = json_decode((string) $response->getBody());
return new BaseResponse(
$jsonObj->status ?? false,
$jsonObj->code ?? null,
$jsonObj->message ?? null ,
$jsonObj->data ?? null
);
}catch(RequestException $e){
// echo Psr7\str($e->getRequest());
// echo Psr7\str($e->getResponse());
$jsonObj = $e->getResponse();
print_r($e->getResponse());
}
return new BaseResponse(
$jsonObj->status ?? false,
$jsonObj->getStatusCode() ?? null,
$jsonObj->getReasonPhrase() ?? null ,
$jsonObj->data ?? null
);
}
public static function requestWithoutAccessToken($method, $url, $params = []){
return ApiCallback::request($method, $url, $params, false);
}
}
final class BaseResponse
{
public $status;
public $code;
public $message;
public $data;
public function __construct($status,$code,$message = "",$data = [])
{
$this->status = $status;
$this->code = $code;
$this->message = $message;
$this->data = $data;
}
}
Additional information:
The REST API is running in localhost with endpoint: /v1/login
The HTTP method is POST
The REST API is using Java Spring Boot v1.5.6
The Request Body is
{
"data":{
"username": "username_string",
"password": "password_string"
}
}
I've tried these clearing caches, and doing composer dump-autoload and the problem still persists
I found the problem and the solution.
So I'm doing some Logging on the exception with Log and found out that my $uri is not valid due my API BASE URL was not found on .env file. So the solution is doing php artisan cache:clear and the guzzle works.
For anyone who reading this question, please remember to try Log if the stack trace didn't help you out.
In my case it was an incorrectly configured error logging remote channel. The error happens on error channel failure, not in your code.
As you mentioned, must either fix the error logging or check logs on server, they have have the original error stack.
I'm building a small application in Laravel 5.5 where I'm using Guzzle Http to get call the api url and get the response, Few of the api calls have certain condition to have headers which works as authorization of the request generated. I'm trying to place the header something like this:
public function post(Request $request)
{
try {
if ($request->url_method == 'get') {
$request = $this->client->get($request->url, [ 'headers' => [ 'access_token' => $request->headers->access_token]]);
}
else if ($request->url_method == 'post')
{ $request = $this->client->post($request->url, [$request->request_data]); }
else { return response()->json(['data' => 'Invalid Method'],500); }
$response = \GuzzleHttp\json_decode($request->getBody());
return response()->json(['data' => json_decode($response->d)], $request->getStatusCode());
}
catch (ClientException $e) {
return response()->json(['data' => 'Invalid Request.'], $request->getStatusCode());
}
}
But this is giving me errors:
Undefined property: Symfony\Component\HttpFoundation\HeaderBag::$access_token
Please checkout the screenshot:
Also when calling through the browser in console it gives me the same error:
Help me out in this, Thanks.
try this code
use GuzzleHttp\Client as GuzzleClient;
..
..
..
$headers = [
'Content-Type' => 'application/json',
'AccessToken' => 'key',
'Authorization' => 'Bearer token',
];
$client = new GuzzleClient([
'headers' => $headers
]);
$body = '{
"key1" : '.$value1.',
"key2" : '.$value2.',
}';
$r = $client->request('POST', 'http://example.com/api/postCall', [
'body' => $body
]);
$response = $r->getBody()->getContents();
Try to add bearer in all small cases before access token like following -
$access_token = 'bearer '.$request->headers->access_token
I have the following code to save content using API from another system. I have added the credentials but it showing wrong credentials error. It is working perfectly in postman.
$client = new GuzzleHttpClient();
try {
$request = new \GuzzleHttp\Psr7\Request('PUT', config('cms.api.backend') .'/products/'. $nid,
[
'auth' => [config('cms.api.user'), config('cms.api.password')],
'form_params' => [
'copywrite' => Input::get('copywrite'),
'status' => $status
],
]);
$promise = $client->sendAsync($request)->then(function ($response) {});
$promise->wait();
}
catch (RequestException $e) {
$this->logHttpError($e->getResponse()->getStatusCode(), $e->getResponse()->getBody(true));
}
What could be wrong in the above code?
Following is the exported code from postman.
$request = new HttpRequest();
$request->setUrl('http://mybackend/api/products/74371');
$request->setMethod(HTTP_METH_PUT);
$request->setHeaders(array(
'postman-token' => 'e0ddcaea-4787-b2c5-0c52-9aaee860ceac',
'cache-control' => 'no-cache',
'authorization' => 'Basic authenticationcode',
'content-type' => 'application/x-www-form-urlencoded'
));
$request->setContentType('application/x-www-form-urlencoded');
$request->setPostFields(array(
'copywrite' => 'date to be saved'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Third argument in \GuzzleHttp\Psr7\Request is for headers array only, so you won't send request body (4th arg) this way. Easiest way would be passing this array as second argument to sendAsync() method. It will recognise them and form_params option will be parsed as Content-Type: application/x-www-form-urlencoded header and create a valid stream for your request (it uses http_build_query() function if you want to do it directly in request constructor):
$request = new \GuzzleHttp\Psr7\Request('PUT', config('cms.api.backend') .'/products/'. $nid);
$options = [
'auth' => [config('cms.api.user'), config('cms.api.password')],
'form_params' => [
'copywrite' => Input::get('copywrite'),
'status' => $status
],
];
$promise = $client->sendAsync($request, $options)->then(function ($response) {});
$promise->wait();
I am trying to build an app in shopify, so uing their API,
as shown here
But while I am requesting a POST request on that URL i.e.
https://demo-store.myshopify.com/admin/script_tags.json
It is returning an error with HTTP status code 400 (Bad Request)
{"errors":{"script_tag":"expected String to be a Hash"}}
Sample code
$access_token = "my-access-token";
$client = new \GuzzleHttp\Client();
try {
$response = $client->request($type, $url,[
'headers' => ['X-Shopify-Access-Token' => $access_token],
'form_params' => ['script_tag'=> \GuzzleHttp\json_encode(["event" => "onload", "src" => "https://app.dev/app.js"])],
]);
$result = json_decode($response->getBody()->getContents(), true);
var_dump($response, $result);
} catch (\Exception $ex) {
var_dump($ex);
}
When making POST or PUT requests to Shopify's API you will usually want a Content-Type: application/json header. Version 6 of Guzzle has a json option that adds the header automatically.
Here's an example of what that could look like when creating a script tag:
$client = new \GuzzleHttp\Client();
$script_tag = [
'script_tag' => [
'src' => 'https://sdks.shopifycdn.com/js-buy-sdk/v0/latest/shopify-buy.umd.polyfilled.min.js',
'event' => 'onload'
]
];
$response = $client->request('POST', 'https://45345345345.myshopify.com/admin/script_tags.json', [
'json' => $script_tag,
'headers' => ['X-Shopify-Access-Token' => $access_token]
]);
I'm doing request to api with Guzzle 6. I want catch HTTP 1.0 401 Unauthorized exception and retry request after get new token. But I can not find examples in the new version documentation.
Events interface had in the old documentation but no event interface new version.
I'm using code this for made request;
public function doSearch(Request $request)
{
$apiData = API::where('id', '1')->first(['api_url', 'api_key']);
try {
$client = new Client([
// Base URI is used with relative requests
'base_uri' => $apiData['api_url'],
'timeout' => 60,
'headers' => [
'Authorization' => 'bearer token',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'verify' => false,
]);
$request = $client->request('POST', '/api/booking/ticket/search', [
'RouteType' => $request->input('type')
]);
} catch (ClientException $e) {
die((string)$e->getResponse()->getBody());
}
$code = $request->getStatusCode(); // 200
$test = $request->getBody()->getContents();
//$test = json_decode($test,true);
return view('front.searchresult');
}
I don't want catch with try-catch code block. I should to renew my desire to create an event listener.
How to catch HTTP Exception and renew request on Guzzle 6?