HTTP requests are classes

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();
    }
}

Usually, we use dependency injection to prepare an HTTP client instance instead of configuring it every time we want to send a request.

However, the HTTP client has to be "configured" every single time we want to make an HTTP request to an external resource, even when the HTTP method and the URL are static.

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();
    }
}

By moving all details about the HTTP request into a separate class, all we have to do to send a request to an external resource and get a response is to call the get method.

This method automatically converts a raw HTTP response to Illuminate\Support\Collection (if possible), or returns a Symfony response class instance (you can also use the getRawContent method to retrieve it).

But what if we want to configure an HTTP request by appending headers, authentication headers?

<?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();
    }
}

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.