Default headers not applying to request - guzzle

New to guzzle. I am trying to use it contact a REST endpoint. Sending the request via curl or using something like postman app for chrome it returns the expected JSON response. Sending it using guzzle below is returning a 404 error similar to what would be returned if I hit the URL without the headers inlcuded.
Why are the headers not making it into this request?
// Get extra detail for the object
$client = new \GuzzleHttp\Client([
'base_uri' => env('OPENIDM_URL'),
'headers' => [
'Content-Type' => 'application/json',
'X-OpenIDM-Username' => env('OPENIDM_USER'),
'X-OpenIDM-Password' => env('OPENIDM_PASS'),
'Authorization' => 'Basic Og=='
]
]);
$request = new \GuzzleHttp\Psr7\Request('GET', $attributes['sourceobjectid']);
$res = $client->send($request);
I have dumped the content of the client and request objects. They look as follows:
Client {#181 ▼
-config: array:8 [▼
"base_uri" => Uri {#188 ▼
-scheme: "https"
-userInfo: ""
-host: "my.url.here.com"
-port: null
-path: "/openidm"
-query: ""
-fragment: ""
}
"headers" => array:5 [▼
"Content-Type" => "application/json"
"X-OpenIDM-Username" => "myuser"
"X-OpenIDM-Password" => "mypass"
"Authorization" => "Basic Og=="
"User-Agent" => "GuzzleHttp/6.2.1 curl/7.38.0 PHP/5.6.26-0+deb8u1"
]
"handler" => HandlerStack {#169 ▶}
"allow_redirects" => array:5 [▶]
"http_errors" => true
"decode_content" => true
"verify" => true
"cookies" => false
]
}
Request {#189 ▼
-method: "GET"
-requestTarget: null
-uri: Uri {#190 ▼
-scheme: ""
-userInfo: ""
-host: ""
-port: null
-path: "managed/user/eb758aab-7896-4196-8989-ba7f97a7e962"
-query: ""
-fragment: ""
}
-headers: []
-headerNames: []
-protocol: "1.1"
-stream: null
Any suggestions would be much appreciated.

If you construct the request object yourself, Guzzle won't apply configurations to it.
You either have to use the convenience HTTP methods (get, put, etc) called from the client or use a custom middleware.
The first one is easier, the second one gives you more power, but responsibility too.

Related

Symfony HttpClient, fail to authenticate external API witch Bearer

I have a problem, I try to use a external API, but the response of that APi is a 401.
1º- I send a request to get the auth token, works fine.
$auth = $this->client->request(
'POST',
'https://api.namebright.com/auth/token',
[
'body' => [
'grant_type' => 'client_credentials',
'client_id' => $clientID,
'client_secret' => $clientSecret,
],
]
);
2º- handler token, i dump the token is loocks fine
$token = sprintf('Bearer %s', $auth->toArray()['access_token']);
3º- I make other request to get the API response, i got a 401.
$response = $this->client->request(
'GET',
'http://api.namebright.com/rest/purchase/availability/google.pt',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => $token,
],
]
);
I don't know what i'm doing wrong. :(
I checked, for responses on the internet and i don't see the problem.
I Tried to change Authorization to authorization.
I tried to check the token in the postmen, works fine.

Convert cURL to Guzzle POST with --form-params and --header

I'm struggling with a given curl-request which I want to handle over guzzle.
The curl-request looks like this:
curl --location --request POST "https://apis.myrest.com" \
--header "Content-Type: multipart/form-data" \
--header "Authorization: Bearer YOUR-BEARER-TOKEN" \
--form "mediaUrl=https://myfile.mpg" \
--form "configuration={
\"speechModel\": { \"language\": \"en-US\" },
\"publish\": {
\"callbacks\": [{
\"url\" : \"https://example.org/callback\"
}]
}
}
And I want it to send via guzzle like that:
// 1. build guzzle client:
//----------------------------------------------------------------------
$this->client = new Client([
'base_uri' => $this->config->getBaseUri(),
]);
// 2. build guzzle request:
//----------------------------------------------------------------------
$request = new Request(
'POST',
'myendpoint',
[
'authorization' => 'Bearer ' . $this->config->getApiToken(),
'cache-control' => 'no-cache',
'content-type' => 'application/json',
// maybe here, or not?
form_params => ['mediaUrl' => 'www.media.com'],
]
);
// 3. send via client
//----------------------------------------------------------------------
response = $this->client->send($request, ['timeout' => self::TIMEOUT]);
My problem now is, that I have no clue how to handle this. In guzzle's documentation i found "form_params":
http://docs.guzzlephp.org/en/stable/quickstart.html#making-a-request#post-form-requests
But it does not seem to work. If I add the form_params-array to my request, the receiver does not get them. Can anybody tell me, how to write the exact curl-command with guzzle?
Thanks
Try using multipart instead of form_params.
http://docs.guzzlephp.org/en/latest/request-options.html#form-params
From Guzzle documentation:
form_params cannot be used with the multipart option. You will need to
use one or the other. Use form_params for
application/x-www-form-urlencoded requests, and multipart for
multipart/form-data requests.
Additionally try setting Guzzle Client with debug on, as it will display raw HTTP request that it sends, so you can compare it more easily with the curl command.
http://docs.guzzlephp.org/en/latest/request-options.html#debug
It is difficult to understand what is the exact request you would like to send, because there is incosistencies between the curl example and your code. I tried to replicate the curl as best as I could. Please note that Request 3rd parameter only expects headers, and for request options you have to use the 2nd parameter of send.
$client = new Client([
'base_uri' => 'https://example.org',
'http_errors' => false
]);
$request = new Request(
'POST',
'/test',
[
'Authorization' => 'Bearer 19237192837129387',
'Content-Type' => 'multipart/form-data',
]
);
$response = $client->send($request, [
'timeout' => 10,
'debug' => true,
'multipart' => [
[
'name' => 'mediaUrl',
'contents' => 'https://myfile.mpg'
],
[
'name' => 'configuration',
'contents' => json_encode([
'speechModel' => [
'language' => 'en-US'
],
'publish' => [
'callbacks' =>
[
[
'url' => 'https://example.org/callback'
]
]
]
])
]
]
]);

guzzle 6 post does not work

I am trying to submit a post with JSON content. I always get this message back:
"Client
error: POST
https://sandbox-api-ca.metrc.com//strains/v1/create?licenseNumber=CML17-0000001
resulted in a 400 Bad Request response: {"Message":"No data was
submitted."}"
(All keys and license number are sandbox. I changed keys slightly so auth wont work. )
here is my code
public function metrc()
{
$client = new Client();
$url = 'https://sandbox-api-ca.metrc.com//strains/v1/create?licenseNumber=CML17-0000001';
$request = $client->post($url, [
'headers' => ['Content-Type' => 'application/json'],
'json' => ['name' => "Spring Hill Kush"],
'auth' => ['kH-qsC1oJPzQnyWMrXjw0EQh812jHOX52ALfUIm-dyE3Wy0h', 'fusVbe4Yv6W1DGNuxKNhByXU6RO6jSUPcbRCoRDD98VNXc4D'],
]);
}
Your code is correct, it should works as expected. Seems that the issue is on the server side. Maybe the format of the POST request is not correct?
BTW, 'headers' => ['Content-Type' => 'application/json'] is unnecessary, Guzzle sets the header by itself automatically when you use json option.

Magento 2 Rest API Order edit

I'm trying to figure out how to edit an order after I requested it.
I made a custom attribute whether an order is exported or not.
I first get all orders with status not exported and after I exported them, I want to change the custom attribute to exported.
What is the REST request to edit/update an order? I keep getting error messages like:
{"message":"%fieldName is a required field.","parameters":
{"fieldName":"entity"}
This is my code:
$json = array(
"entity_id" => $id,
"extension_attributes" => array(
"custom_export_attribute" => "exported",
)
);
$webapi = new ApiClient('https://dev.local.nl', self::$username, self::$password);
$response = $webapi->getClient()->request('PUT', '/rest/V1/orders/create', [
'headers' => [
'Authorization' => "Bearer " . $webapi->getToken(),
'Content-Type' => "application/json"
],
'body' => json_encode($json)
]);
return json_decode($response->getBody(), true);
I also tried:
$webapi->getClient()->request('PUT', '/rest/V1/orders/'.$id,
To edit / update order details, the Magento 2 /V1/orders accepts POST request method. As per Magento 2 Dev Doc, it accepts the request body in below format (You can find whole JSON request in documentation page):
{
"entity": {
"entity_id": 0,
"extension_attributes": {
}
}
}
So, you just need to update the $json variable as:
$json = [
"entity"=> [
"entity_id" => $id,
"extension_attributes" => [
"custom_export_attribute" => "exported"
]
]
]
And than invoke with POST request method instead of PUT. In my suggestion prefer to use Create API for new order creation.

OneDrive REST API error 400 when creating folder

I have a problem when trying to create a folder in my OneDrive using the REST API. I'm using following documentation page https://dev.onedrive.com/items/create.htm. I have successfully authenticated and the token is working ok on other endpoints.
I spent now over a day trying every possible URI/method combination on this one but with no success. All other endpoints (directory listing etc.) are OK, just this one is driving me crazy.
If anyone could point me to the error in my approach, any help would be appreciated.
The code below returns error 400 with following message:
{"error":{"code":"invalidRequest","message":"The request is malformed or incorrect."}}
I'm using GuzzlePhp library for the request handling. My code (simplified):
$parentId = '01WZZ7ZY2LNHB75JADQJD3GGUQFSCRRZTQ'; //id to root
$method = "POST";
//none of these does the trick (to be clear, I use only one at the time)
$url = '/_api/v2.0/drive/items/'.$parentId.'/NewFolder'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //post
$url = '/_api/v2.0/drive/root:/NewFolder'; //post
$options = [
'headers' => [
'Authorization' => $token,
'Content-Type' => 'application/json',
'Content-Length'=> 0,
]
'form_params' => [
"name" => "NewFolder",
"folder" => (object)[],
"#name.conflictBehavior" => "fail"
]
];
//Guzzle library sends the code as specified
$res = $this->client->request($method, $url, $options);
The OneDrive API doesn't support form post semantics - the parameters are expected in the body as a JSON encoded blob. I haven't used Guzzle, but something like this should work:
$parentId = '01WZZ7ZY2LNHB75JADQJD3GGUQFSCRRZTQ'; //id to root
$method = "POST";
//none of these does the trick (to be clear, I use only one at the time)
$url = '/_api/v2.0/drive/items/'.$parentId.'/NewFolder'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //post
$url = '/_api/v2.0/drive/root:/NewFolder'; //post
$options = [
'headers' => [
'Authorization' => $token,
'Content-Type' => 'application/json',
'Content-Length'=> 0,
]
'body' =>
'{
"name": "NewFolder",
"folder": { },
"#name.conflictBehavior": "fail"
}'
];
//Guzzle library sends the code as specified
$res = $this->client->request($method, $url, $options);