Laravel 7 HTTP Client - Unable to send POST request with `body` - laravel

Using Laravel 7.6 and it's built-in HTTP Client.
I'm trying to send a simple POST request with body in Raw JSON format to my other domain but no luck:
$response = Http::post('https://example.com', [
'body' => '{ test: 1 }'
]);
I get 400 Bad Request - Client error - because my server expects body as a mandatory.
What am I missing here?

$response = Http:post('http://example.com/', [
'foo' => 'bar'
]);
Or this
$response = Http::withHeaders([
'User-Agent' => 'Some Agent',
])->asForm()->post('http://www.example.com/', [
'foo' => 'bar',
]);

Try this, in my case this should works.
$response = Http::withHeaders(['Content-Type' => 'application/json'])
->send('POST', 'https://example.com', [
'body' => '{ test: 1 }'
])->json();

Related

Laravel not making Guzzle HTTP POST request correctly

I am working on a megento integration and trying to get the admin access token by making a post request with form data. I tested the route out on Postman and it worked correctly:
However, when I tried to implement the same request in Laravel with Guzzle Http Client, it seem just cannot make the request properly as if the form data post body is not being recognized, and it keeps showing me errors saying the field values are required. Here is my request:
$client = new \GuzzleHttp\Client();
$response = $client->post($request['magento_domain'] . '/rest/V1/integration/admin/token', [
'form_params' => [
'username' => $magento_admin_username,
'password' => $magento_admin_password
], [
'Accept' => 'application/json',
'Content-Type' => 'application/json'
]
]);
and then this is the error I keep getting:
Update: I had also tried the request like this, it throws the same error:
$response = $client->post($request['magento_domain'] . '/rest/V1/integration/admin/token', [
'form_params' => [
'username' => $magento_admin_username,
'password' => $magento_admin_password
]
]);
I would appreciate any help!
The "Content-Type: application/json" request header is incorrect when sending a form-data body.
Just remove it, Guzzle automatically adds the correct Content-Type when using "form_params". Just JSON is wrong because the body is obviously not JSON.
I am using a JSON request in production successfully:
$res = $this->client->request('POST', 'https://.../rest/V1/integration/admin/token', [
'headers' => [
'Accept' => 'application/json',
'content-type' => 'application/json'
],
'json' => [
'username' => config('app.shopUser'),
'password' => config('app.shopPw')
]
]);
Or try using "multipart" instead of "form_params" - this should send a multipart/form-data request which is what Postman means with "form-data".
"form_params" is equivalent to "x-www-form-urlencoded".

Error: Pass content as json or plain text

I am using guzzle to post data to the api as below. When i post, the api returns Error: Pass content as json or plain text. Is it possible to convert content to JSON or Plain Text in the code below
How can I resolve this?
Controller
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded',
];
$client = new \GuzzleHttp\Client([
'headers' => $headers
]);
$body = '{
"item" : Summer-Jacket,
"content" : Hi
}';
$url = "https://api.com";
$request = $client->post($url,
[
'body' => $body
] );
$response = $request->send();
Firstly your body is not even valid JSON. Strings needs to have "string" around them
To post JSON with guzzle, you can instead use the RequestOptions for exactly that.
$result = $client->post("https://api.com", [
RequestOptions::JSON => [
'item' => 'Summer-Jacket',
'content' => 'hi',
]
)->getBody();

form_params method get guzzle php

I have an API get list user. postmen
and Headers Content-Type = application/json
- In laravel, I use guzzle to call api
code demo:
$client = new Client();
$headers = ['Content-Type' => 'application/json'];
$body = [
'json' => [
"filter" => "{}",
"skip" => 0,
"limit" => 20,
"sort" => "{\"createAt\": 1}",
"select" => "fullname username",
"populate" => "'right', 'group'",
]
];
\Debugbar::info($body);
$response = $client->get('http://sa-vn.com:2020/api/users/user', [
'form_params' => $body
]);
echo $response->getBody();
But it does not working! please help me
form_params and body both are different params in guzzle. check json
$json = [
"filter" => json_encode((object)[]),
"skip" => 0,
"limit" => 20,
"sort" => json_encode((object)['createAt'=>1]),
"select" => "fullname username",
"populate" => "'right', 'group'"
];
$response = $client->request('get', 'http://sa-vn.com:2020/api/users/user', [
'json' => $json,
]);
If any error occur try without json_encode as well.
$json = [
"filter" => (object)[],
"skip" => 0,
"limit" => 20,
"sort" => (object)['createAt'=>1],
"select" => "fullname username",
"populate" => "'right', 'group'"
];
As per Guzzle doucmentation
form_params
Used to send an application/x-www-form-urlencoded POST request.
json
The json option is used to easily upload JSON encoded data as the body of a request. A Content-Type header of application/json will be added if no Content-Type header is already present on the message.
You are passing json data in postman. So you can use json instead of form_params
Change
$response = $client->get('http://sa-vn.com:2020/api/users/user', [
'form_params' => $body
]);
to
$response = $client->get('http://sa-vn.com:2020/api/users/user', [
'json' => $body
]);

Can’t submit data to API Platform

I have a controller through which I send data to my local environment of the api platform (which is running fine)
/**
* Creates a new Location entity.
*
*/
public function createAction(Request $request)
{
$this->get("suvya_breadcrumbs.factory")->update('New Hub');
$form = $this->createForm(HubType::class);
$form->handleRequest($request);
$new_url = $this->generateUrl('new_hub');
$redirect_url = $this->generateUrl('home');
if ($form->isSubmitted() && $form->isValid()) {
$client = new Client([
'base_uri' => 'http://127.0.0.1:8000',
]);
$response = $client->request('POST', '/hubs', [
'form_params'=> $form->getData(),
'headers' => [
'Accept' => 'application/ld+json',
'Content-Type'=> 'application/json',
'Authorization'=> 'eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTUxNzg3NjE1NCwiZXhwIjoxNTE3ODc5NzU0fQ.gIG9lueJJZxzkOl8qblhHWwiJvW97m4gz1-1mYeM9SgMzMW35Wh6XamOOYiISDN99yJ6Ovo-wKk6whpE5UGMDVw_wGek003Dd6r-Y7Ql3kVLHksn2JFzhAN3GwlXFcOI4MIjmq5qBhkzv21pHymO0yn1SlzWBwb0O7WygywefMu5p09zGuvAiP9I2ShyQLZhjj8bB_odf3dI-Ql0ZbRmn_JDkDoPcm5U11i-3S1oMikBmFq0WtTcWo7vezt3QdA3bY4_bgaISINAiYRR-_cvjpBSqFSE6n1ZYtHvKFn-98wXXsBGxEAoZw6iQL4iRgOI8F_uaiCo0eRHC7q0_xQ_V_W0-5XDIQXWDwoiVaUXnjO6xo2Fldp7PLO1ueJz1e4wiOy2-TunZdc8UCtw2BdFIQtWatPLi_v_rsNvF2H-6hwa9UOKEi9Z4tH4KkuATbXAxxfkCbSOyY1SAWP0riooPQi_AI2J7L2Ly86eAuKo1Hix3EuEogo19GSyBz_cCWczyERQWM9gikuUs8E22SIAdxTl8ZLFaXgiZIibDvb8pqcN8izFjywWbF2CkyWC58WxrVd6Bfmfnm7k9T6oZqwIZ-TQR-SbRnUHN1hpWUjFCk-tHhgvh7osHXmxe3grzA8M3LPBpQGQiTeqBZFMjF4Tx8zW2tuiEn6TwhV14Lj24Vc'
]
]);
die();
}
return $this->render('SuvyaFabricsCloudBundle:Common:basic.html.twig', array(
'form' => $form->createView(),
'page_title'=> 'Hub aanmaken',
'action_path' => $new_url,
'cancel_path'=> $redirect_url,
'submit_button_title' => 'Opslaan',
));
}
But unfortunately i'm getting an error in my dev.log of the api environment:
[2018-02-06 02:32:37] request.INFO: Matched route "api_hubs_post_collection". {"route":"api_hubs_post_collection","route_parameters":{"_controller":"api_platform.action.post_collection","_format":null,"_api_resource_class":"AppBundle\\Entity\\Hub","_api_collection_operation_name":"post","_route":"api_hubs_post_collection"},"request_uri":"http://127.0.0.1:8000/hubs","method":"POST"} []
[2018-02-06 02:32:37] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Serializer\Exception\UnexpectedValueException: "Syntax error" at /Users/myname/Sites/suvyalogistics-api/vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/JsonDecode.php line 78 {"exception":"[object] (Symfony\\Component\\Serializer\\Exception\\UnexpectedValueException(code: 0): Syntax error at /Users/myname/Sites/suvyalogistics-api/vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/JsonDecode.php:78)"} []
The output of form->getData():
array (size=4)
'postalCode' => string 'sdfdsf' (length=6)
'streetName' => string 'sdfsdf' (length=6)
'doorNumber' => string 'sdfsfd' (length=6)
'city' => string 'sdfsfd' (length=6)
Running the endpoint at the api platform with the same values goes fine as well.
Does anyone of you has an idea why this goes wrong?
You're sending a payload encoded in application/x-www-form-urlencoded (HTML form like) to the API Platform API, while, according to the headers you've set, it excepts data encoded in JSON.
To encode the data of the form in JSON, you can use the following Guzzle snippet:
$client = new Client([
'base_uri' => 'http://127.0.0.1:8000',
]);
$response = $client->request('POST', '/hubs', [
'json' => $form->getData(),
'headers' => [
'Accept' => 'application/ld+json',
'Authorization'=> '...'
]
]);
Alternatively, you can configure API Platform to accept form data, but I would not recommend going this way (it's better to only deal with JSON API-side).

guzzle client throws exception in laravel

I am trying to make a http post request in laravel as below
$client = new Client(['debug'=>true,'exceptions'=>false]);
$res = $client->request('POST', 'http://www.myservice.com/find_provider.php', [
'form_params' => [
'street'=> 'test',
'apt'=> '',
'zip'=> 'test',
'phone'=> 'test',
]
]);
It return empty response. On debugging ,following exception is occurring
curl_setopt_array(): cannot represent a stream of type Output as a STDIO FILE*
I am using latest version of guzzle.
Any idea how to solve it?.
The request() method is returning a GuzzleHttp\Psr7\Response object.
To get the actual data that is returned by your service you should use:
$data = $res->getBody()->getContents();
Now check what you have in $data and if it corresponds to the expected output.
More information on using Guzzle Reponse object here
I had to do this
$data = $res->getBody()->getContents();<br>
but also change<br>
$client = new \GuzzleHttp\Client(['verify' => false, 'debug' => true]);<br>
to<br>
$client = new \GuzzleHttp\Client(['verify' => false]);
Here is what i did for my SMS api
use Illuminate\Support\Facades\Http; // Use this on top
// Sample Code
$response = Http::asForm()
->withToken(env('SMS_AUTH_TOKEN'))
->withOptions([
'debug' => fopen('php://stderr', 'w') // Update This Line
])
->withHeaders([
'Cache-Control' => 'no-cache',
'Content-Type' => 'application/x-www-form-urlencoded',
])
->post($apiUrl,$request->except('_token'));

Resources