The Guzzle HTTP client has been added to Drupal core.
Introduction
Guzzle supports many features that drupal_http_request() currently does not, like an object oriented and easier to use API, error-handling using exceptions and better support for the HTTP standard. Guzzle also has a modern architecture, which can be extended with plugins to support requesting mocking for tests, caching and much more.
Guzzle can be accessed through the http_client service and the \Drupal::httpClient() helper method, like this $client = \Drupal::httpClient();
This returns an instance of Client. In the typical use case, an instance of GuzzleHttp\Message\RequestInterface is instantiated like this:
$client = \Drupal::httpClient();
$request = $client->createRequest('GET', $feed->url);
Call $response = $client->send($request); to send the request, this method returns an instance of the GuzzleHttp\Message\Response class.
More detailed API documentation and usage examples can be found in the official Guzzle documentation. Note that Drupal currently only includes the base HTTP component of Guzzle.
Example code
7.x
$headers = array('If-Modified-Since' => gmdate(DATE_RFC1123, $last_fetched));
$result = drupal_http_request($feed->url, array('headers' => $headers));
if ($result->code == 200) {
// Expected result.
$data = $result->data;
}
else {
// Error handling.
}
8.x
$client = \Drupal::httpClient();
$request = $client->createRequest('GET', $feed->url);
$request->addHeader('If-Modified-Since', gmdate(DATE_RFC1123, $last_fetched));
try {
$response = $client->get($feed->uri, [
'headers' => [
'If-Modified-Since' => gmdate(DATE_RFC1123, $last_fetched),
],
]);
// Expected result.
// getBody() returns an instance of Psr\Http\Message\StreamInterface.
// @see http://docs.guzzlephp.org/en/latest/psr7.html#body
$data = $response->getBody();
}
catch (RequestException $e) {
watchdog_exception('my_module', $e);
}
In case of an error, guzzle will throw an exception. Some examples include:
- TransferException
-- RequestException
--- BadResponseException
---- ClientException
---- ServerException
--- TooManyRedirectsException
To simply handle and log an error in case something goes wrong, a single catch for RequestException and passing that exception to watchdog_exception() is enough. More specific exception handling is possible by adding additional catch blocks for e.g. the BadResponseException, which has a getResponse method that allows to get and do something with the returned HTTP response.
Comments
Program to an interface not an implementation??
Is there a reason we couldn't have put Guzzle behind drupal_http_request?
The logic of including Guzzle is sound, but do we have to change the interface every time we introduce something new.
Too complex
An HTTP client is too complex to be able to throw our own interface around it without cutting off 90% of the functionality. We tried. It's not worth the effort.
If you really want to use an HTTP client other than Guzzle for your own code, it's all just composer libraries so you can pull in your own and use it. They'll co-exist happily.
--
Larry Garfield
http://www.garfieldtech.com/
Thinking Functionally in PHP: https://leanpub.com/thinking-functionally-in-php
D8 example appears incorrect
Update: Looks like the page has been updated to reflect this comment, thanks to ingaro.
The D8 code doesn't appear to work anymore. Looks like there's no longer a
createRequest()method in Guzzle.Per the Guzzle Documentation, this should work for the example above:
Following Code is working for
Following Code is working for me
http://drupal.stackexchange.com/questions/187697/what-is-the-equivalent-...
Nested arrays have issues with Guzzle
https://www.drupal.org/node/2691645 describes in detail.
-Jesse of http://www.jesselongacre.com
Interesting problem
I have a site with an API:
http://www.sitename.com/api/popular!getAsJson.action?period=10days
I have a code:
but I can`t get the response right, when I enter the url directly on the browser I see the right response.
Please help!
I think you have to either
I think you have to either use the casting operator like:
or use getContents() method as:
More details here: http://stackoverflow.com/a/30549372
createRequest is no longer in Guzzle, but still in the example
As mentioned in one of the other comments, createRequest is no longer a thing. The same comment also suggests that the example has been updated, but actually they still mention createRequest? Is there a reason, or shall I jump in and change it up?
At the same time, I see that it might not make sense to keep a change log up to date with all the subsequent api changes... but the page is so chock-full of useful information for D7 people looking to do an http request in D8 that it would be good to either update or to put a big obvious link to the appropriate documentation.
Create request and Create Response
This is in Drupal library in /core/lib/Drupal/Core/Http/TrustedHostsRequestFactory.php
$request = $client->createRequest(); // - creates request
// and after we can
$response = $client->send($request);
$client->request() // - creates response
$response = $client->request('GET',$uri);
Updated example with some options
The d8 code in the docs doesn't seem to work with D8.3, and I've been struggling to find
any examples of making more than a simple get request.
Here's an example of making a POST request, with http authentication, custom headers and
posting form data:
Request pools in 8.3
Just wanted to point something out. Since the createRequest() method is no longer available, you can do the same thing this way:
Request with cookies
If you need to handle session (or other) cookies with the request, check the core test for an example
https://api.drupal.org/api/drupal/core%21modules%21system%21tests%21src%...
--
Perttu Ehn
Working example sending a XML with \Drupal::httpClient() POST
This is working for me, sending a XML file with \Drupal::httpClient() POST
Hope this help.