handle http_erros when posting with guzzle - php

I am trying to test a function that when called, returns error 500 from the server. i was able to do the same when using get like this:
public function testApiAd_idNotExists(){
$path = '/adserver/src/public/api/ad/98765432123456789';
$client = new Client(['base_uri' => 'http://10.0.0.37']);
$response = $client->get($path, ['http_errors' => false]);
$err = $response->getStatusCode();
$this->assertEquals($err, 404);
}
but when i tried doing the same with post it didn't work. In the guzzle documentation i cant find anything about http_errors and posting.
this is my attempt which is not working:
public function testApiAd_postIllegalProviderId(){
$client = new Client();
$url = 'http://10.0.0.38/adserver/src/public/api/ad';
$response = $client->post($url, ['form_params' => [
'name' => 'bellow content - guzzle testing',
'widget_id' => '1010101010',
]],['http_errors' => false]);
$err = $response->getStatusCode();
$this->assertEquals($err, 500);
}
any idea how can i do that?? thx!

Related

Using guzzle to post to Facebook Conversions API [duplicate]

Does anybody know the correct way to post JSON using Guzzle?
$request = $this->client->post(self::URL_REGISTER,array(
'content-type' => 'application/json'
),array(json_encode($_POST)));
I get an internal server error response from the server. It works using Chrome Postman.
For Guzzle 5, 6 and 7 you do it like this:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
GuzzleHttp\RequestOptions::JSON => ['foo' => 'bar'] // or 'json' => [...]
]);
Docs
The simple and basic way (guzzle6):
$client = new Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $client->post('http://api.com/CheckItOutNow',
['body' => json_encode(
[
'hello' => 'World'
]
)]
);
To get the response status code and the content of the body I did this:
echo '<pre>' . var_export($response->getStatusCode(), true) . '</pre>';
echo '<pre>' . var_export($response->getBody()->getContents(), true) . '</pre>';
For Guzzle <= 4:
It's a raw post request so putting the JSON in the body solved the problem
$request = $this->client->post(
$url,
[
'content-type' => 'application/json'
],
);
$request->setBody($data); #set body!
$response = $request->send();
This worked for me (using Guzzle 6)
$client = new Client();
$result = $client->post('http://api.example.com', [
'json' => [
'value_1' => 'number1',
'Value_group' =>
array("value_2" => "number2",
"value_3" => "number3")
]
]);
echo($result->getBody()->getContents());
$client = new \GuzzleHttp\Client();
$body['grant_type'] = "client_credentials";
$body['client_id'] = $this->client_id;
$body['client_secret'] = $this->client_secret;
$res = $client->post($url, [ 'body' => json_encode($body) ]);
$code = $res->getStatusCode();
$result = $res->json();
You can either using hardcoded json attribute as key, or you can conveniently using GuzzleHttp\RequestOptions::JSON constant.
Here is the example of using hardcoded json string.
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
'json' => ['foo' => 'bar']
]);
See Docs.
$client = new \GuzzleHttp\Client(['base_uri' => 'http://example.com/api']);
$response = $client->post('/save', [
'json' => [
'name' => 'John Doe'
]
]);
return $response->getBody();
This works for me with Guzzle 6.2 :
$gClient = new \GuzzleHttp\Client(['base_uri' => 'www.foo.bar']);
$res = $gClient->post('ws/endpoint',
array(
'headers'=>array('Content-Type'=>'application/json'),
'json'=>array('someData'=>'xxxxx','moreData'=>'zzzzzzz')
)
);
According to the documentation guzzle do the json_encode
Solution for $client->request('POST',...
For those who are using $client->request this is how you create a JSON request:
$client = new Client();
$res = $client->request('POST', "https://some-url.com/api", [
'json' => [
'paramaterName' => "parameterValue",
'paramaterName2' => "parameterValue2",
]
'headers' => [
'Content-Type' => 'application/json',
]
]);
Guzzle JSON Request Reference
Php Version: 5.6
Symfony version: 2.3
Guzzle: 5.0
I had an experience recently about sending json with Guzzle. I use Symfony 2.3 so my guzzle version can be a little older.
I will also show how to use debug mode and you can see the request before sending it,
When i made the request as shown below got the successfull response;
use GuzzleHttp\Client;
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
"Content-Type" => "application/json"
];
$body = json_encode($requestBody);
$client = new Client();
$client->setDefaultOption('headers', $headers);
$client->setDefaultOption('verify', false);
$client->setDefaultOption('debug', true);
$response = $client->post($endPoint, array('body'=> $body));
dump($response->getBody()->getContents());
#user3379466 is correct, but here I rewrite in full:
-package that you need:
"require": {
"php" : ">=5.3.9",
"guzzlehttp/guzzle": "^3.8"
},
-php code (Digest is a type so pick different type if you need to, i have to include api server for authentication in this paragraph, some does not need to authenticate. If you use json you will need to replace any text 'xml' with 'json' and the data below should be a json string too):
$client = new Client('https://api.yourbaseapiserver.com/incidents.xml', array('version' => 'v1.3', 'request.options' => array('headers' => array('Accept' => 'application/vnd.yourbaseapiserver.v1.1+xml', 'Content-Type' => 'text/xml'), 'auth' => array('username#gmail.com', 'password', 'Digest'),)));
$url = "https://api.yourbaseapiserver.com/incidents.xml";
$data = '<incident>
<name>Incident Title2a</name>
<priority>Medium</priority>
<requester><email>dsss#mail.ca</email></requester>
<description>description2a</description>
</incident>';
$request = $client->post($url, array('content-type' => 'application/xml',));
$request->setBody($data); #set body! this is body of request object and not a body field in the header section so don't be confused.
$response = $request->send(); #you must do send() method!
echo $response->getBody(); #you should see the response body from the server on success
die;
--- Solution for * Guzzle 6 * ---
-package that you need:
"require": {
"php" : ">=5.5.0",
"guzzlehttp/guzzle": "~6.0"
},
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.compay.com/',
// You can set any number of default request options.
'timeout' => 3.0,
'auth' => array('you#gmail.ca', 'dsfddfdfpassword', 'Digest'),
'headers' => array('Accept' => 'application/vnd.comay.v1.1+xml',
'Content-Type' => 'text/xml'),
]);
$url = "https://api.compay.com/cases.xml";
$data string variable is defined same as above.
// Provide the body as a string.
$r = $client->request('POST', $url, [
'body' => $data
]);
echo $r->getBody();
die;
Simply use this it will work
$auth = base64_encode('user:'.config('mailchimp.api_key'));
//API URL
$urll = "https://".config('mailchimp.data_center').".api.mailchimp.com/3.0/batches";
//API authentication Header
$headers = array(
'Accept' => 'application/json',
'Authorization' => 'Basic '.$auth
);
$client = new Client();
$req_Memeber = new Request('POST', $urll, $headers, $userlist);
// promise
$promise = $client->sendAsync($req_Memeber)->then(function ($res){
echo "Synched";
});
$promise->wait();
I use the following code that works very reliably.
The JSON data is passed in the parameter $request, and the specific request type passed in the variable $searchType.
The code includes a trap to detect and report an unsuccessful or invalid call which will then return false.
If the call is sucessful then json_decode ($result->getBody(), $return=true) returns an array of the results.
public function callAPI($request, $searchType) {
$guzzleClient = new GuzzleHttp\Client(["base_uri" => "https://example.com"]);
try {
$result = $guzzleClient->post( $searchType, ["json" => $request]);
} catch (Exception $e) {
$error = $e->getMessage();
$error .= '<pre>'.print_r($request, $return=true).'</pre>';
$error .= 'No returnable data';
Event::logError(__LINE__, __FILE__, $error);
return false;
}
return json_decode($result->getBody(), $return=true);
}
The answer from #user3379466 can be made to work by setting $data as follows:
$data = "{'some_key' : 'some_value'}";
What our project needed was to insert a variable into an array inside the json string, which I did as follows (in case this helps anyone):
$data = "{\"collection\" : [$existing_variable]}";
So with $existing_variable being, say, 90210, you get:
echo $data;
//{"collection" : [90210]}
Also worth noting is that you might want to also set the 'Accept' => 'application/json' as well in case the endpoint you're hitting cares about that kind of thing.
Above answers did not worked for me somehow. But this works fine for me.
$client = new Client('' . $appUrl['scheme'] . '://' . $appUrl['host'] . '' . $appUrl['path']);
$request = $client->post($base_url, array('content-type' => 'application/json'), json_encode($appUrl['query']));

HTTP Guzzle not returning all data

I have created a function that contacts a remote API using Guzzle but I cannot get it to return all of the data available.
I call the function here:
$arr = array(
'skip' => 0,
'take' => 1000,
);
$sims = api_request('sims', $arr);
And here is the function, where I have tried the following in my $response variable
json_decode($x->getBody(), true)
json_decode($x->getBody()->getContents(), true)
But neither has shown any more records. It returns 10 records, and I know there are over 51 available that it should be returning.
use GuzzleHttp\Client;
function api_request($url, $vars = array(), $type = 'GET') {
$username = '***';
$password = '***';
//use GuzzleHttp\Client;
$client = new Client([
'auth' => [$username, $password],
]);
$auth_header = 'Basic '.$username.':'.$password;
$headers = ['Authorization' => $auth_header, 'Content-Type' => 'application/json'];
$json_data = json_encode($vars);
$end_point = 'https://simportal-api.azurewebsites.net/api/v1/';
try {
$x = $client->request($type, $end_point.$url, ['headers' => $headers, 'body' => $json_data]);
$response = array(
'success' => true,
'response' => // SEE ABOVE //
);
} catch (GuzzleHttp\Exception\ClientException $e) {
$response = array(
'success' => false,
'errors' => json_decode($e->getResponse()->getBody(true)),
);
}
return $response;
}
By reading the documentation on https://simportal-api.azurewebsites.net/Help/Api/GET-api-v1-sims_search_skip_take I assume that the server is not accepting your parameters in the body of that GET request and assuming the default of 10, as it is normal in many applications, get requests tend to only use query string parameters.
In that function I'd try to change it in order to send a body in case of a POST/PUT/PATCH request, and a "query" without json_encode in case of a GET/DELETE request. Example from guzzle documentation:
$client->request('GET', 'http://httpbin.org', [
'query' => ['foo' => 'bar']
]);
Source: https://docs.guzzlephp.org/en/stable/quickstart.html#query-string-parameters

Client Error 404 not found when sending a post request with guzzle

I want to send a post request to an external api using guzzle , but i get this error :
Client error: POST https://api.platform.ly/ resulted in a 404 Not Found response:
{"status":"error","message":"Missing Parameters"}
$client = new \GuzzleHttp\Client();
$url = "https://api.platform.ly/";
$body['api_key'] = ENV('PLATFORMLY_KEY');
$body['action'] = 'add_contact';
$body['value'] = [
'project_id' => '1589',
'email' => $user->email,
'name' => $user->name
];
$request = $client->post($url, ['form_params'=>$body]);
dd($request);
$response = $request->send();
dd($response);
This should fix your problem. A JSON string is needed on the value field per platformly docs, so utilize json_encode like so.
$body['value'] = json_encode([
'project_id' => '1589',
'email' => $user->email,
'name' => $user->name
]);
I had the same issue and it took a min to figure it out because it wasn't clear.
Here is your code snippet with json_encode implemented.
$client = new \GuzzleHttp\Client();
$url = "https://api.platform.ly/";
$body['api_key'] = ENV('PLATFORMLY_KEY');
$body['action'] = 'add_contact';
$body['value'] = json_encode([
'project_id' => '1589',
'email' => $user->email,
'name' => $user->name
]);
$request = $client->post($url, ['form_params'=>$body]);
dd($request);
$response = $request->send();
dd($response);

API response returns JSON without Response Body

Using Guzzle, I'm consuming some external apis in JSON format,
usually I get the data with
$data = $request->getBody()->getContents();
But i can't get data from this different api.
It seems the data doesn't come in a 'Response Body'.
This api call works:
https://i.ibb.co/80Yk6dx/Screenshot-2.png
This doesn't work:
https://i.ibb.co/C239ghy/Screenshot-3.png
public function getRemoteCienciaVitaeDistinctions()
{
$client = new Client(['headers' => ['Accept' => 'application/json']]);
$request = $client->get(
'https://................/',
[
'auth' => ['...', '...'],
]
);
$data = $request->getBody()->getContents();
return $data;
}
the second call is working fine, but the response is empty,
as we can see in Screenshot-3, the Total = 0, so the response from this API is empty.
to handle that properly I suggest you this modification for your method :
public function getRemoteCienciaVitaeDistinctions()
{
$client = new Client(['headers' => ['Accept' => 'application/json']]);
$request = $client->get(
'https://................/',
[
'auth' => ['...', '...'],
]
);
//Notice that i have decoded the response from json objects to php array here.
$response = json_decode($request->getBody()->getContents());
if(isset($response->total) && $response->total == 0) return [];
return $response;
}
please check the documentation of the API that you are using

How can I use Guzzle to send a POST request in JSON?

Does anybody know the correct way to post JSON using Guzzle?
$request = $this->client->post(self::URL_REGISTER,array(
'content-type' => 'application/json'
),array(json_encode($_POST)));
I get an internal server error response from the server. It works using Chrome Postman.
For Guzzle 5, 6 and 7 you do it like this:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
GuzzleHttp\RequestOptions::JSON => ['foo' => 'bar'] // or 'json' => [...]
]);
Docs
The simple and basic way (guzzle6):
$client = new Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $client->post('http://api.com/CheckItOutNow',
['body' => json_encode(
[
'hello' => 'World'
]
)]
);
To get the response status code and the content of the body I did this:
echo '<pre>' . var_export($response->getStatusCode(), true) . '</pre>';
echo '<pre>' . var_export($response->getBody()->getContents(), true) . '</pre>';
For Guzzle <= 4:
It's a raw post request so putting the JSON in the body solved the problem
$request = $this->client->post(
$url,
[
'content-type' => 'application/json'
],
);
$request->setBody($data); #set body!
$response = $request->send();
This worked for me (using Guzzle 6)
$client = new Client();
$result = $client->post('http://api.example.com', [
'json' => [
'value_1' => 'number1',
'Value_group' =>
array("value_2" => "number2",
"value_3" => "number3")
]
]);
echo($result->getBody()->getContents());
$client = new \GuzzleHttp\Client();
$body['grant_type'] = "client_credentials";
$body['client_id'] = $this->client_id;
$body['client_secret'] = $this->client_secret;
$res = $client->post($url, [ 'body' => json_encode($body) ]);
$code = $res->getStatusCode();
$result = $res->json();
You can either using hardcoded json attribute as key, or you can conveniently using GuzzleHttp\RequestOptions::JSON constant.
Here is the example of using hardcoded json string.
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
'json' => ['foo' => 'bar']
]);
See Docs.
$client = new \GuzzleHttp\Client(['base_uri' => 'http://example.com/api']);
$response = $client->post('/save', [
'json' => [
'name' => 'John Doe'
]
]);
return $response->getBody();
This works for me with Guzzle 6.2 :
$gClient = new \GuzzleHttp\Client(['base_uri' => 'www.foo.bar']);
$res = $gClient->post('ws/endpoint',
array(
'headers'=>array('Content-Type'=>'application/json'),
'json'=>array('someData'=>'xxxxx','moreData'=>'zzzzzzz')
)
);
According to the documentation guzzle do the json_encode
Solution for $client->request('POST',...
For those who are using $client->request this is how you create a JSON request:
$client = new Client();
$res = $client->request('POST', "https://some-url.com/api", [
'json' => [
'paramaterName' => "parameterValue",
'paramaterName2' => "parameterValue2",
]
'headers' => [
'Content-Type' => 'application/json',
]
]);
Guzzle JSON Request Reference
Php Version: 5.6
Symfony version: 2.3
Guzzle: 5.0
I had an experience recently about sending json with Guzzle. I use Symfony 2.3 so my guzzle version can be a little older.
I will also show how to use debug mode and you can see the request before sending it,
When i made the request as shown below got the successfull response;
use GuzzleHttp\Client;
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
"Content-Type" => "application/json"
];
$body = json_encode($requestBody);
$client = new Client();
$client->setDefaultOption('headers', $headers);
$client->setDefaultOption('verify', false);
$client->setDefaultOption('debug', true);
$response = $client->post($endPoint, array('body'=> $body));
dump($response->getBody()->getContents());
#user3379466 is correct, but here I rewrite in full:
-package that you need:
"require": {
"php" : ">=5.3.9",
"guzzlehttp/guzzle": "^3.8"
},
-php code (Digest is a type so pick different type if you need to, i have to include api server for authentication in this paragraph, some does not need to authenticate. If you use json you will need to replace any text 'xml' with 'json' and the data below should be a json string too):
$client = new Client('https://api.yourbaseapiserver.com/incidents.xml', array('version' => 'v1.3', 'request.options' => array('headers' => array('Accept' => 'application/vnd.yourbaseapiserver.v1.1+xml', 'Content-Type' => 'text/xml'), 'auth' => array('username#gmail.com', 'password', 'Digest'),)));
$url = "https://api.yourbaseapiserver.com/incidents.xml";
$data = '<incident>
<name>Incident Title2a</name>
<priority>Medium</priority>
<requester><email>dsss#mail.ca</email></requester>
<description>description2a</description>
</incident>';
$request = $client->post($url, array('content-type' => 'application/xml',));
$request->setBody($data); #set body! this is body of request object and not a body field in the header section so don't be confused.
$response = $request->send(); #you must do send() method!
echo $response->getBody(); #you should see the response body from the server on success
die;
--- Solution for * Guzzle 6 * ---
-package that you need:
"require": {
"php" : ">=5.5.0",
"guzzlehttp/guzzle": "~6.0"
},
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.compay.com/',
// You can set any number of default request options.
'timeout' => 3.0,
'auth' => array('you#gmail.ca', 'dsfddfdfpassword', 'Digest'),
'headers' => array('Accept' => 'application/vnd.comay.v1.1+xml',
'Content-Type' => 'text/xml'),
]);
$url = "https://api.compay.com/cases.xml";
$data string variable is defined same as above.
// Provide the body as a string.
$r = $client->request('POST', $url, [
'body' => $data
]);
echo $r->getBody();
die;
Simply use this it will work
$auth = base64_encode('user:'.config('mailchimp.api_key'));
//API URL
$urll = "https://".config('mailchimp.data_center').".api.mailchimp.com/3.0/batches";
//API authentication Header
$headers = array(
'Accept' => 'application/json',
'Authorization' => 'Basic '.$auth
);
$client = new Client();
$req_Memeber = new Request('POST', $urll, $headers, $userlist);
// promise
$promise = $client->sendAsync($req_Memeber)->then(function ($res){
echo "Synched";
});
$promise->wait();
I use the following code that works very reliably.
The JSON data is passed in the parameter $request, and the specific request type passed in the variable $searchType.
The code includes a trap to detect and report an unsuccessful or invalid call which will then return false.
If the call is sucessful then json_decode ($result->getBody(), $return=true) returns an array of the results.
public function callAPI($request, $searchType) {
$guzzleClient = new GuzzleHttp\Client(["base_uri" => "https://example.com"]);
try {
$result = $guzzleClient->post( $searchType, ["json" => $request]);
} catch (Exception $e) {
$error = $e->getMessage();
$error .= '<pre>'.print_r($request, $return=true).'</pre>';
$error .= 'No returnable data';
Event::logError(__LINE__, __FILE__, $error);
return false;
}
return json_decode($result->getBody(), $return=true);
}
The answer from #user3379466 can be made to work by setting $data as follows:
$data = "{'some_key' : 'some_value'}";
What our project needed was to insert a variable into an array inside the json string, which I did as follows (in case this helps anyone):
$data = "{\"collection\" : [$existing_variable]}";
So with $existing_variable being, say, 90210, you get:
echo $data;
//{"collection" : [90210]}
Also worth noting is that you might want to also set the 'Accept' => 'application/json' as well in case the endpoint you're hitting cares about that kind of thing.
Above answers did not worked for me somehow. But this works fine for me.
$client = new Client('' . $appUrl['scheme'] . '://' . $appUrl['host'] . '' . $appUrl['path']);
$request = $client->post($base_url, array('content-type' => 'application/json'), json_encode($appUrl['query']));

Categories