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

G Http Laravel Package

jaeger/g-http

jaeger/g-http is a lightweight Guzzle-based HTTP client for PHP with a simple API for GET/POST requests, headers, cookies, proxies, and concurrent async calls, making it useful for scraping, API integration, and Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

jaeger/g-http (Jae\GHttp\GHttp) is a thin convenience wrapper around Guzzle, so installation is a single Composer line:

composer require jaeger/g-http

There is no service provider, no Facade, and no config/ file — it is a plain PHP class you instantiate yourself. So the first step in a Laravel app is to decide where it lives:

  1. Open vendor/jaeger/g-http/src/GHttp.php first. It is small; read the actual public method signatures before writing anything. The mental model to confirm: a new GHttp() object holds default headers/cookies/timeout/proxy/retry settings, and exposes get(), post(), put(), delete(), etc., each returning a Guzzle ResponseInterface.
  2. Resolve it once (bind a singleton or just new GHttp() in a service) rather than scattering imports.
  3. Your first realistic use case: a scheduled command or a one-off integration that needs to call a third-party JSON API and doesn't warrant a full client class:
use Jae\GHttp\GHttp;

$http = new GHttp();
$http->setHeaders(['Accept' => 'application/json']);
$response = $http->get('https://api.example.com/v1/status');
$data = json_decode($response->getBody()->getContents(), true);

If you are already inside Laravel and only need this for one call, stop and use the framework's Http:: facade instead — it covers the same ground with better ergonomics and testing support.

Implementation Patterns

Wrap it in a dedicated client class. Because the package has no container integration, the cleanest day-to-day pattern is a small service that owns a configured GHttp instance:

class BillingClient
{
    private GHttp $http;

    public function __construct()
    {
        $this->http = new GHttp();
        $this->http->setHeaders([
            'Authorization' => 'Bearer '.config('services.billing.token'),
            'Accept'        => 'application/json',
        ]);
        $this->http->setTimeout(10);
        $this->http->setConnectTimeout(3);
    }

    public function invoice(int $id): array
    {
        $res = $this->http->get("https://billing.example.com/invoices/{$id}");
        return json_decode($res->getBody()->getContents(), true);
    }
}

Bind BillingClient as a singleton in a service provider if you want connection reuse semantics to be predictable.

Use it where the Laravel HTTP client is a poor fit. Good fits: artisan commands, queue jobs that shell out, standalone scripts bootstrapped against the Laravel container, or package code that must not depend on Illuminate\Support\Facades\Http. For anything that needs Http::fake() in tests, prefer the framework client.

Configuration as defaults, not per-call. The package's setters (setHeaders, setCookies, setProxy, setTimeout, setConnectTimeout, setVerify, setRetry) mutate instance state, so treat each instance as a configured profile. Build one "authed + JSON" instance and one "public + short timeout" instance rather than reconfiguring a shared object mid-request.

Retry at the boundary. If the wrapper exposes a retry setting, use it only for idempotent GETs. For POSTs, wrap the call in your own try/catch and retry() (Laravel helper) so you control backoff and side-effect safety.

Response handling. Returns are Guzzle responses, so the same idioms apply: $response->getStatusCode(), $response->getBody()->getContents() (consumes the stream — read once), and header access via $response->getHeaderLine('...'). Cast JSON with json_decode(..., true, 512, JSON_THROW_ON_ERROR) inside your wrapper so failures surface as your exception type.

Gotchas and Tips

  • No framework glue. There is nothing to php artisan vendor:publish, no config, no Facade. If you want GHttp::get(...)-style static access, build your own facade or a app()->make() accessor.
  • Guzzle exceptions leak through. Non-2xx responses throw GuzzleHttp\Exception\* (ClientException / ServerException) unless http_errors is disabled on the underlying client. Catch RequestException and log $e->getResponse() body — otherwise you get opaque 500s in your app.
  • Body streams are one-shot. Calling getContents() twice returns an empty string the second time. Decode once and pass the array around.
  • TLS verification is a footgun. Many tiny wrappers default verify to false for convenience. Check setVerify() behavior in source; in production you want verification on, and if a vendor cert is broken, fix the trust store rather than disabling verification globally.
  • Retry + non-idempotent verbs. Automatic retry on POST can double-charge. Confirm what the package retries before trusting the setting.
  • Abandoned-ish surface area. 19 stars, 0 dependents, minimal maintenance means you are effectively the maintainer. Pin an exact version in composer.json, and be ready to fork: the entire library is one file, so replacing it with a 40-line Guzzle wrapper is a realistic escape hatch.
  • Debugging. Guzzle's debug option (if exposed via client construction) logs raw request/response to stderr; otherwise use Laravel's Http::fake() on the equivalent framework call, or drop a Log::debug() around status code + body length in your wrapper. $response->getConfig()/$client->getConfig() helps confirm headers actually sent.
  • Testability. Without a package testing hook, unit tests should mock your own BillingClient wrapper, not GHttp. That's another reason to wrap early — it isolates you from the package's API surface.
  • Proxy/cookie state is shared per instance. A long-lived singleton with cookies set will carry that cookie jar across users/jobs. Use per-job instances when cookie state matters.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib