Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Simple Http Client Laravel Package

mj4444/simple-http-client

A lightweight, easy-to-use HTTP client for Laravel and PHP applications. mj4444/simple-http-client provides a straightforward way to make outgoing requests and handle responses, keeping common API calls simple and readable in your code. It aims to reduce boilerplate for common HTTP calls.

View on GitHub
Deep Wiki
Context7

Getting Started

This is an unvetted package (0 stars, 0 dependents, Unlicense). Treat the first 10 minutes as a code review, not a setup.

  1. Read the package before installing it. It is almost certainly a handful of files:

    composer require mj4444/simple-http-client
    ls -R vendor/mj4444/simple-http-client/src
    cat vendor/mj4444/simple-http-client/composer.json
    

    From composer.json, confirm three things: the PSR-4 namespace, whether it declares extra.laravel.providers (auto-discovery) or needs manual registration, and which HTTP transport it depends on — Guzzle directly, or illuminate/http. That single fact determines every pattern below.

  2. Look first at the client class constructor. The constructor signature is the whole API surface: does it take a base URI, a Guzzle ClientInterface, a config array, or nothing? Note whether it returns a PSR-7 ResponseInterface, a decoded array, or throws on 4xx/5xx. You need this before you write a single call.

  3. Smoke-test in Tinker before wiring anything up.

    $c = app(\Mj4444\SimpleHttpClient\Client::class);
    dump($c->get('https://httpbin.org/get'));
    

    If binding fails, it is not auto-discovered — register it manually in AppServiceProvider::register() or add the provider to bootstrap/providers.php.

  4. First real use case: one read-only GET against a third-party JSON API, wrapped in a small adapter class of your own (see below). Do not call the package directly from controllers, jobs, or commands — the whole point of the adapter is that you can rip the package out in an afternoon.

If step 1 shows a package that is little more than a file_get_contents wrapper, or that hardcodes curl_* calls, stop and use Laravel's Http facade instead — you lose nothing and gain Http::fake(), retries, and a maintained dependency.

Implementation Patterns

Bind behind your own interface. The package name advertises simplicity, which usually means a thin, non-final class with no interface of its own. Create one:

interface RatesApi { public function latest(string $base): array; }

final class SimpleClientRatesApi implements RatesApi
{
    public function __construct(private \Mj4444\SimpleHttpClient\Client $client) {}

    public function latest(string $base): array
    {
        $response = $this->client->get("https://api.example.com/latest?base={$base}");
        return json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
    }
}

Bind it in a provider, inject RatesApi everywhere, and the package name never appears outside that one file.

One adapter per upstream service. Do not build a generic ApiService that takes a URL argument — you get a God object with an untested HTTP client at its core. Adapters also give you a natural place to normalise the package's return type into your own DTOs.

Configure, don't hardcode. Put base URLs and timeouts in config/services.php and pass them into the client at construction. If the package has no config file of its own, publish nothing — just build the client in your provider:

$this->app->singleton(Client::class, fn () => new Client(
    baseUri: config('services.rates.base_url'),
    timeout: config('services.rates.timeout', 5),
));

Adjust to the real constructor; the shape is what matters.

Push calls to the queue. Any outbound HTTP call is a latency and failure source. Wrap adapter calls in a job with $tries, backoff(), and failed() handling rather than making a request inline in a web request.

Add resilience at the adapter, not in the package. If the package exposes no retry mechanism (likely), implement it in the adapter or a decorator:

final class RetryingRatesApi implements RatesApi
{
    public function __construct(private RatesApi $inner) {}
    public function latest(string $base): array
    {
        return retry(3, fn () => $this->inner->latest($base), 200, fn ($e) => true);
    }
}

Decorate the interface binding, not the concrete client — no forking required.

Testing. If the package wraps Laravel's Http, Http::fake() covers you for free. If it wraps Guzzle, catch the client in the container: build a MockHandler + HandlerStack and bind a Guzzle client returning canned responses. Either way, fake at the interface boundary in feature tests and reserve transport-level fakes for the adapter's own unit test.

Gotchas and Tips

  • Zero dependents means zero field testing. You are the first person to hit whatever bug exists. Pin the exact version ("mj4444/simple-http-client": "1.0.0", not ^1.0), commit composer.lock, and read the changelog before any update. If the source is under a few hundred lines, consider vendoring it into app/Support/ and dropping the dependency — the maintenance cost is near zero and you gain full control.
  • Guzzle version conflicts are the most likely install failure. Laravel already constrains guzzlehttp/guzzle; if this package requires an older major, Composer will either refuse to install or silently downgrade Guzzle and break something else. Run composer why guzzlehttp/guzzle after install and check composer update --dry-run output before merging.
  • Establish the error contract explicitly. The most common trap with thin clients is that a 500 response is returned as a normal value rather than thrown, so json_decode yields null and you get a confusing TypeError three layers up. Write one test that asserts behaviour on 404, 500, and a non-JSON body, and add an explicit $response->getStatusCode() >= 400 guard in your adapter if the package doesn't throw.
  • Watch for a missing timeout. Hand-rolled curl_* clients frequently set none, and PHP's default default_socket_timeout of 60s will pin a queue worker for a minute per call. Always pass your own timeout at the adapter level.
  • Unlicense means no warranty and no security response channel. There is no maintainer obligated to patch a CVE, and no SECURITY.md. For anything touching credentials or PII, prefer Illuminate\Support\Facades\Http, which gives you the same simplicity with a maintained supply chain.
  • Check for auto-discovery before assuming binding works. A package with extra.laravel absent will fail app(Client::class) with "Target is not instantiable" — the fix is registering it yourself, not debugging the container.
  • Debug by logging the raw exchange. Add a decorator around the adapter that logs method, URL (with query string redacted), status, and elapsed ms to a dedicated channel. Without this, failures inside a job are invisible until retries exhaust.
  • Extension points are probably nonexistent. Don't count on middleware hooks, events, or a tap() method. The reliable extension point is the decorator pattern around your own interface — design for that from the start and the package's internal limitations stop mattering.

Bottom line: usable as an implementation detail behind one adapter, not as infrastructure. Before adopting, spend the ten minutes in vendor/ to confirm it does what the name implies; if it doesn't clearly beat Http::get()->throw()->json(), take the facade.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table