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 Factory Laravel Package

http-interop/http-factory

http-interop/http-factory defines standard interfaces for creating PSR-7 HTTP messages and URIs, providing a PSR-17 precursor API that decouples your code from concrete HTTP implementations. Install via Composer for interoperable factory support.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is an implementation of the PSR-17 HTTP factory interfaces (RequestFactoryInterface, ResponseFactoryInterface, StreamFactoryInterface, UploadedFileFactoryInterface, UriFactoryInterface). In a Laravel app you'll reach for it when something needs to create PSR-7 messages rather than consume them — custom streamed responses, building requests for a PSR-18 client, or satisfying a third-party package that type-hints a factory interface.

Read the release note first: 0.4.1 is the final release and the package is deprecated. That changes the "getting started" step from "install it" to "decide whether to install it at all."

  1. Check whether you already have a PSR-17 implementation transitively:
    composer show | grep -i psr
    composer why psr/http-factory
    
    Guzzle pulls in guzzlehttp/psr7, which already provides factories. If that's present, you likely don't need this package.
  2. If you do need it in an existing app, pin the final version deliberately and record the deprecation:
    composer require <vendor>/<package>:^0.4.1
    
  3. Look first at the package's service provider (if it registers one) and its factory classes — that's where the container bindings for the five interfaces live. Confirm which concrete class backs each interface before you type-hint anything.
  4. First use case to validate with: inject ResponseFactoryInterface into a controller or a small action class and return $responseFactory->createResponse(200)->withBody($streamFactory->createStream($json)). If that round-trips through your test suite, the wiring is correct.

For new work, start on the replacement path instead: composer require psr/http-factory (interfaces) plus a maintained implementation such as nyholm/psr7 or guzzlehttp/psr7, and bind those factories in your own service provider.

Implementation Patterns

Bind interfaces, never concrete classes. The whole value of PSR-17 is that your code type-hints Psr\Http\Message\ResponseFactoryInterface. Register the bindings in a PsrServiceProvider so that replacing the implementation later is a one-line change in a provider rather than a search-and-replace across the app:

$this->app->bind(ResponseFactoryInterface::class, fn () => new ResponseFactory());
$this->app->bind(StreamFactoryInterface::class, fn () => new StreamFactory());
// ...request, uri, uploaded file

Factory + PSR-18 client is the common pairing. Factories create the request, the client sends it. Keeping the factory injection separate from the client injection makes tests trivial: swap the client for a mock, leave the factory real.

Use factories in custom responses. Laravel's Response doesn't speak PSR-7, so if a package hands you a StreamInterface you need a stream factory to build one from a string or a resource, and a response factory to wrap it. A small StreamedJsonResponse-style class is the usual home for this.

Prefer factories over new Response(...) in reusable code. If you're writing a package or a shared domain service, new-ing a concrete PSR-7 class couples you to one implementation. Inject the factory instead — even if today there's only one implementation in the tree.

Test doubles are cheap. A fake ResponseFactoryInterface returning a real Response is a few lines; use it in unit tests so you never boot the container just to get a message object.

Migration pattern for the deprecation. Because the interfaces are the stable contract, the swap is mechanical: add psr/http-factory + a maintained implementation, point your existing bindings at the new concrete classes, remove this package. Anything type-hinting the interfaces — which should be everything — keeps compiling. Do it as two commits (add+bind, then remove) so a rollback is clean.

Gotchas and Tips

  • The package is abandoned as of 0.4.1. No security fixes, no PHP version bumps. This is the single most important fact about it. Treat the migration as scheduled work, not backlog trivia — a future PHP or PSR-7/PSR-17 patch release can break it silently.
  • psr/http-factory is interfaces only. The release note's advice is correct but incomplete: switching to psr/http-factory gives you the contracts, not a working factory. You must also pick an implementation (nyholm/psr7, guzzlehttp/psr7, laminas-diactoros). Don't swap the dependency and assume factories still resolve — the container binding will fail at runtime, not at boot.
  • Duplicate implementation hazard. If Guzzle is installed, guzzlehttp/psr7 is already on disk and already satisfies the interfaces. Two implementations means two sets of bindings and confusing composer why output. Audit before adding anything.
  • 0.x versions carry no BC promise. Even before the abandonment notice, a 0.4 → 0.5 bump was allowed to break signatures. Pin to ^0.4.1 and note the pin in your upgrade docs.
  • Check the binding scope. If the provider registers factories as singletons, be aware factory objects are stateless and that's fine — but a stream created from a shared resource is not. Don't cache StreamInterface instances in the container.
  • Debugging: if you get Target [Psr\Http\Message\ResponseFactoryInterface] is not instantiable, the provider isn't registered or the package's auto-discovery is disabled in composer.json. Run php artisan about / check bootstrap/providers.php and config/app.php for the provider entry.
  • Extension point: rather than forking the package for a small tweak, write your own thin factory class implementing the interface and bind that. It's less code than a fork and it survives the removal of the package entirely.
  • Audit call sites before removing. grep -rn "Psr\\\\Http\\\\Message" app/ to confirm nothing type-hints a concrete class from this package. Anything that does is the actual blocker for migration.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums