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

Http Laravel Package

swlib/http

swlib/http is a lightweight HTTP message library for PHP and Swoole, providing request, response, URI, and stream objects for coroutine-friendly clients and servers. It offers a simple foundation for building HTTP interactions without heavy framework dependencies.

Deep Wiki
Context7

Getting Started

composer require swlib/http

The package ships no Laravel service provider, config file, or facade — there is nothing to register. Everything lives under the Swlib\Http\ namespace and is a set of concrete PSR-7 (Psr\Http\Message\*) implementations built on top of Guzzle's guzzlehttp/psr7 code, so the mental model is: these are Request/Response/Uri/Stream value objects, not a client.

Where to look first:

  1. composer.json — confirm which psr/http-message version it targets (^1.0 vs ^2.0) and which Guzzle it borrows from. This is the single most important file, because it determines whether it will coexist with your existing guzzlehttp/guzzle install.
  2. src/Request.php, src/Response.php, src/Uri.php, src/Stream.php — the PSR-7 surface you'll actually touch.
  3. Any MessageTrait / StreamTrait — that's where the Guzzle-derived immutability and header handling lives.

First use case: you have a Psr\Http\Message\ServerRequestInterface consumer (a middleware, a PSR-15 handler, an SDK, a signed-webhook verifier) and you need to hand it a request object constructed from Laravel's Illuminate\Http\Request:

use Swlib\Http\Uri;
use Swlib\Http\Request;
use Swlib\Http\Stream;

$laravel = request();

$psr = (new Request($laravel->method(), new Uri($laravel->fullUrl())))
    ->withBody(Stream::create($laravel->getContent()))
    ->withHeaders($laravel->headers->all());

That conversion is the realistic day-to-day entry point in a Laravel app; you rarely instantiate these classes to send traffic.

Implementation Patterns

Adapter between Illuminate\Http\Request and PSR-7. Wrap the conversion in a small dedicated class (App\Http\Psr7\FromLaravelRequest) and register it as a singleton. Keeping the mapping in one place means header casing, query parsing, and body handling stay consistent across controllers, listeners, and queued jobs.

final class Psr7Factory
{
    public function fromLaravel(\Illuminate\Http\Request $r): \Psr\Http\Message\ServerRequestInterface
    {
        $uri = new Uri($r->fullUrl());

        return (new ServerRequest($r->method(), $uri, $r->headers->all()))
            ->withBody(Stream::create($r->getContent()))
            ->withQueryParams($r->query->all())
            ->withParsedBody($r->isJson() ? $r->json()->all() : $r->post());
    }
}

Pairing with a PSR-18 client. If you'd rather depend on Psr\Http\Client\ClientInterface than on GuzzleHttp\Client directly, these objects slot in as the request/response types:

$response = $client->sendRequest(
    (new Request('POST', new Uri('https://api.example.com/hooks')))
        ->withHeader('Content-Type', 'application/json')
        ->withBody(Stream::create(json_encode($payload)))
);

if ($response->getStatusCode() >= 400) {
    throw new \RuntimeException((string) $response->getBody());
}

Bind the client interface in a service provider and this package becomes the only PSR-7 dependency you need to know about in your domain code.

Middleware / pipeline usage. A PSR-15 middleware stack (or a hand-rolled pipeline for webhook handling) can consume the ServerRequest produced by the factory, mutate it immutably, and hand it to your handler. Because every with*() returns a clone, you can safely pass the same base request into several branches of a pipeline without defensive copying.

Converting back out. When you need to return a PSR-7 ResponseInterface from a Laravel route (e.g. a package that emits PSR-7 responses), map status, headers, and body onto an Illuminate\Http\Response in the controller rather than trying to teach Laravel about PSR-7.

Testing. The value objects are trivially constructible in isolation; use them directly in unit tests for services that accept Psr\Http\Message\* so you don't have to boot the framework or spin up a fake HTTP kernel.

Gotchas and Tips

  • Maintenance risk is the headline issue. Last release 2020-08-15, 11 stars, no visible activity. Treat it as frozen code: it works or it doesn't, and nothing will be patched. Pin the exact version in composer.json and be prepared to swap to guzzlehttp/psr7 or nyholm/psr7 — the PSR-7 interface means the swap is a namespace change, not a rewrite.
  • Duplicate PSR-7 implementations in one app. Laravel pulls in guzzlehttp/psr7 transitively through guzzlehttp/guzzle. Installing swlib/http gives you a second set of classes satisfying the same interfaces. That's fine at the interface boundary, but type-hint Psr\Http\Message\RequestInterface, never Swlib\Http\Request, in service signatures — otherwise you've hard-coupled your domain to a dead package.
  • PSR-7 v1 vs v2 signatures. The 2020 timeframe means it almost certainly targets psr/http-message: ^1.0. If another dependency requires ^2.0, Composer will either fail to resolve or install a second psr/http-message major — neither is pleasant. Check composer why psr/http-message before adding it to an existing project.
  • Immutability is easy to forget. $request->withHeader(...) returns a new object; the original is untouched. In Laravel's mutable-request world this trips people up constantly. Assign the result: $request = $request->withHeader(...).
  • Streams are single-read. Body streams have a cursor. If you (string) $response->getBody() once, calling it again may yield an empty string. Call $stream->rewind() first, or cast once and cache.
  • URI encoding quirks. The Guzzle-derived Uri will percent-encode and normalize as Guzzle does — double-encoding of already-encoded query strings is a classic surprise. Build query params via withQueryParams() rather than string concatenation.
  • No container bindings, no config. There's nothing to php artisan vendor:publish. If you want a singleton factory, write it yourself in AppServiceProvider; the package intentionally stays out of the framework's way.
  • Debugging. var_dump/dd on these objects dumps the whole stream and headers; use $request->getMethod(), (string) $request->getUri(), $request->getHeaders() explicitly. For stream contents, (string) $request->getBody() after a rewind().
  • Extension points are thin. Because it's a Guzzle derivative, the practical extension path is to stop extending and instead rely on PSR-7/PSR-18 interfaces. If you find yourself needing to patch behavior, that's the signal to migrate off the package.
  • Autoload/namespace check. If you get "class not found" after install, run composer dump-autoload; small packages occasionally ship PSR-0-style or mismatched namespaces that need a refresh.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin