oscarotero/psr7-middlewares
A collection of PSR-7 middleware for PHP, including authentication, caching, CORS, HTTPS, and routing. Works with any PSR-7 compatible framework or application.
Architecture fit — poor for in-app use, narrow otherwise.
Laravel's HTTP layer is built on Symfony HttpFoundation (Illuminate\Http\Request/Response), not PSR-7. This package targets PSR-7 pipelines from the Slim 3 / Zend Expressive / Relay era: callable-chained middleware that takes and returns Psr\Http\Message\RequestInterface / ResponseInterface. These are not PSR-15 MiddlewareInterface implementations and cannot be registered in app/Http/Kernel.php. Adopting them means standing up a second middleware paradigm beside Laravel's, connected by a bidirectional bridge (symfony/psr-http-message-bridge plus a PSR-7 implementation).
That constraint reframes the evaluation: the package is not a Laravel dependency, it is a specification of behaviors — CORS, HTTPS enforcement, client IP resolution, content negotiation, payload parsing, error handling, cache headers, redirects — for which Laravel and Symfony already ship first-party equivalents.
Integration feasibility — technically possible, strategically weak. Two viable shapes:
Technical risk — high and structural, not incidental.
psr/http-message ^1.0 and zendframework/zend-diactoros era. Expect resolution failures against Laravel 10/11 and modern Guzzle/Laminas stacks. Verify with composer why-not before any design work.^5.6 || ^7.0; implicit-nullable and return-type deprecations under 8.2+ are probable. Verify by running the suite on your target runtime in a scratch container.opportunity: 0.54 is consistent with "well-regarded in its time, now a reference artifact."Key questions for the team:
HandleCors, TrustProxies, URL::forceScheme('https'), $request->isJson(), and Symfony's AcceptHeader cover them?Stack fit. Low for app/Http/Kernel.php. Moderate only at the edges: a PSR-7 sidecar, a third-party-facing middleware package, or an outbound HTTP client stack. Inside a Laravel request lifecycle it competes with built-ins that are already tested, documented, and upgraded with the framework.
Migration path — do not migrate; translate.
| Package middleware | Laravel-native equivalent |
|---|---|
| CORS | HandleCors (framework built-in) |
| HTTPS enforcement | URL::forceScheme('https') + web-server redirect |
| Client IP helpers | TrustProxies + $request->ip() |
| Content negotiation | Symfony AcceptHeader, $request->accepts() |
| Payload parsing | $request->json(), form request validation |
| Cache headers | Cache-Control response middleware |
| Redirects | RedirectResponse / Redirector |
Sequence:
HttpMiddleware interface and never register it in the default kernel path. Spike fails → reimplement the residual behaviors natively; treat the package as a reference implementation.Middlewares\*, so rip-out is a one-file change.Compatibility checks before commitment. composer why-not oscarotero/psr7-middlewares against the target Laravel version; a container build on the production PHP minor; a PSR-7 implementation choice that matches psr/http-message 1.x if the package pins it; and a header/body fidelity test on file uploads and streamed responses.
Maintenance. Effectively zero upstream. Archive status means you own every future fix, including transitive CVEs. Budget a named internal owner, a pinned version (or vendored fork), and a documented security exception with sign-off. If that owner doesn't exist, the answer is no.
Support. No vendor, no maintainer triage, no issue tracker with a future. Knowledge concentrates in whoever builds the bridge — a bus factor of one unless the shim is written down and peer-reviewed.
Scaling. The PSR-7 ↔ HttpFoundation conversion is not free. Body handling is the risk: naive bridges materialize the entire body as a string, which is fine for small JSON APIs and a memory problem for large uploads and streamed responses. Header conversion is where correctness breaks first — multi-value headers, Set-Cookie arrays, and host/scheme detection through proxies. Expect no throughput benefit; the win, if any, is code reuse.
Failure modes to instrument and test:
HandleCors) → duplicated headers, broken preflight.TrustProxies → wrong rate limits, poisoned audit logs, bad geo.Ramp-up. The team knows Laravel middleware, not callable-chained PSR-7 pipelines. Adopting this introduces a persistent two-paradigm confusion in code review ("why isn't this in the kernel?"). Budget an onboarding note plus one pairing session, and expect at least one production incident traced to the bridge within the first quarter if it sits on the hot path.
TPM recommendation. Do not take a runtime dependency. Use the package as a well-written reference for HTTP behavior, harvest the two or three middlewares that lack a native equivalent, and keep the Laravel request lifecycle single-paradigm. Revisit only if an actual PSR-7/PSR-15 interoperability requirement appears — and then evaluate a maintained PSR-15 library rather than a 2017 archive.
How can I help you explore Laravel packages today?