Laravel 7 was recently released on 3rd March 2020. It is an exciting release with a few noted new features aimed at improving the performance of the Laravel framework as well as the Developer Experience.
One of these features that was implemented by Taylor and discussed at Laracon is the addition of a revised wrapper over Guzzle. For those that don't know, Guzzle is a PHP HTTP client that has been the defacto-standard for HTTP requests in PHP since around 5.6.
The new wrapper for Laravel uses the HTTP namespace and is a wrapper over Adam Wathan's ZTTP project. ZTTP is a simple Guzzle Wrapper for the most common use cases of making API requests.
Essentially Laravel 7 integrates ZTTP (with some minor tweaks) to Laravel so that you can use the HTTP Facade to make requests using ZTTP (and by extension Guzzle).
This is a great change as it improves the developer experience of making API requests and still leverages a great HTTP framework (in Guzzle) under the hood.
Show me the code!
Let's look at some examples!
Making a simple GET request to our example-api in Guzzle is the following:
$client = new GuzzleHttp\Client(['base_uri' => 'https://example.com/api/']); $response = $client->request('GET', 'posts');
The above code is rather simplistic, we simply defined a Guzzle Client and set our API base URI to
https://example.com/api and then we used our instantiated Client to do a GET request to
/posts/ so our full qualified URI is now as follows
https://example.com/api/posts. It works! And it's rather simplistic however if we look at the Laravel 7 equivalent, we get the following:
use Illuminate\Support\Facades\Http; $response = Http::get('https://example.com/api/posts'));
Note that we have not necessarily had to setup the Client as this is handled by Laravel under the hood.
However that was a naive example, how about something that falls within the 90% use case such as doing a POST request with JSON-encoded params in the Body of our request. In Guzzle, we could do the following:
$client = new GuzzleHttp\Client(['base_uri' => 'https://example.com/api/']); $response = $client->request('POST', 'posts', [ 'laravel_version' => '7', 'details' => '123', ] ]);
That is relatively self explanatory however what is the equivalent using Laravel 7's HTTP facade? Well...
$response = Http::post('https://example.com/api/posts', [ 'laravel_version' => '7', 'details' => '123', ]);
Both approaches above are accomplishing the same thing and it is important to note that Laravel's HTTP Facade (or Zttp for that matter) is not attempting to clone Guzzle. Guzzle is a large library in itself and it is just aiming at simplifying the 90% use case which is satisfactory for most Developers.
Let's look at something a bit more complicated, how about API authentication? It is very important to authenticate to your desired API before making requests in order to ensure that your API calls are secure and that you are authorized to perform certain actions. It's a basic principal of OWASP when dealing with authentication.
Let's assume we are doing authentication via a Bearer Token.
Let's assume we have our token and are making a POST request, in Guzzle we could do the following by setting our Bearer token in our Headers.
$client = new GuzzleHttp\Client([ 'base_uri' => 'https://example.com/api/', 'Authorization' => 'Bearer ' . 'our-example-token', 'Accept' => 'application/json', ]); $response = $client->request('POST', 'posts', [ 'laravel_version' => '7', 'details' => '123', ] ]);
While in comparison with Laravel 7:
$response = Http::withHeaders( ['Authorization' => 'Bearer' . 'our-example-token'] )->post($url, [ 'laravel_version' => '7', 'details' => '123', ]);
It definitely looks a lot cleaner! In general, the Laravel service wrapper over Zttp is mainly just to speed up development and improve the Developer Experience of using Guzzle. Ironically the same reason why Guzzle was developed as a way to improve upon raw CURL requests.
Should I use Guzzle or Laravel 7's Http Facade?
The burning question, Like most tools, it depends... Laravel's Http Facade is great for the 90% use case however if you are doing anything outside of normal API integrations or need extensive control over every feature in the Guzzle API then rather stick with that. You will see more of this feature in newer posts whereby I will look at how to build an API in Laravel 7. If you want to read more on Laravel's HTTP Facade in the meantime, then please refer to the documentation.
Till next time!