Let's say you want to make an HTTP query from a Laravel application. It will probably look something like this:
<?php
// Bunch of imports...
class TestServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->when(TestController::class)
->needs(Client::class)
->give(function () {
return new Client([
'base_uri' => 'https://rust-lang.org',
]);
});
}
}
class TestController extends Controller
{
protected Client $client;
public function __construct(Client $client)
{
$this->client = $client;
}
public function test()
{
return (string) $this->client->request('GET', 'learn')
->getBody();
}
}
At first, it seems normal: we use dependency injection to prepare an HTTP client instance instead of configuring it every time we want to send a request.
However, this HTTP client isn't bounded by anything at all.
Instead, we can write something like...
<?php
// Other imports...
use Ivan770\HttpClient\Request\Request;
class LearnRequest extends Request
{
protected $resource = "https://rust-lang.org/learn";
}
class TestController extends Controller
{
public function test(LearnRequest $learnRequest)
{
return $learnRequest->get();
}
}
As you can see, we moved all details about the HTTP request into the separate class, and all we have to do to receive a response is to call the get
method.
This method automatically converts a raw HTTP response to Illuminate\Support\Collection
(if it's possible), or returns a Symfony response class instance otherwise (you can also use the getRawContent
method to retrieve it).
But that example was fairly simple - no headers, authentication, etc. What about something a bit more complicated?
<?php
// Other imports...
use Ivan770\HttpClient\HttpClient;
use Ivan770\HttpClient\Request\Request;
class LearnRequest extends Request
{
protected $resource = "https://httpbin.org/post";
protected $method = "POST";
protected function defaultAttach(HttpClient $client)
{
// https://github.com/ivan770/laravel-httpclient/blob/master/src/HttpClient.php
$client->authBearer("MyCoolToken")
->headers([
"hello" => "world"
]);
}
}
class TestController extends Controller
{
public function test(LearnRequest $learnRequest)
{
return $learnRequest->get();
}
}
And how is that different from just creating a new HTTP client instance every time you want to send a request?
With LearnRequest
encapsulating all HTTP request details, you only have to call the get
method to retrieve a response information, without worrying about the request specifics.
Of course, you may need to pass some local information to an HTTP request before sending it. For example, we can add a Bearer token to the request before running it:
<?php
// Other imports...
use Ivan770\HttpClient\HttpClient;
use Ivan770\HttpClient\Request\Request;
class LearnRequest extends Request
{
protected $resource = "https://httpbin.org/post";
protected $method = "POST";
protected function defaultAttach(HttpClient $client)
{
$client->headers([
"hello" => "world"
]);
}
}
class TestController extends Controller
{
public function test(LearnRequest $learnRequest)
{
return $learnRequest->authBearer("TestToken")
->get();
}
}
You can also add custom methods to your HTTP request classes to encapsulate authentication token management, headers, etc.