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

Middleman Laravel Package

mindplay/middleman

PSR-15 middleware dispatcher for PHP that composes middleware into a single request handler. Supports lazy middleware resolution from a PSR-11 container, class-name based middleware, and PSR-7/PSR-15 stacks, making it easy to build clean, layered HTTP applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • mindplay/middleman is a generic PSR-15 MiddlewareInterface / PSR-7 dispatcher: it resolves middleware from a PSR-11 container, chains them via RequestHandler delegates, and returns a PSR-7 ResponseInterface. It has no Laravel awareness — no service provider, no facade, no HTTP-kernel hook, no config.
  • Laravel's native request pipeline is Illuminate\Pipeline\Pipeline driven by Illuminate\Foundation\Http\Kernel, with its own contracts (handle($request, Closure $next)), middleware groups, priority ordering, terminable middleware, and Request/Response subclasses. Those are not PSR-15/PSR-7. Adopting Middleman means running a second, parallel middleware engine rather than extending the existing one.
  • Therefore the only defensible fit is a PSR-first subsystem: a package or route group we intend to keep framework-agnostic, or a service we may later lift out of Laravel. For ordinary app/Http/Middleware work, Middleman is an impedance mismatch with no functional gain over the framework pipeline.

Integration feasibility

  • Feasible but non-trivial. It requires a PSR-7 bridge in both directions: symfony/psr-http-message-bridge + a PSR-7/PSR-17 implementation (nyholm/psr7 or guzzlehttp/psr7) to convert Laravel's Request inbound and PSR-7 Response outbound. Every request pays a conversion cost and body re-buffering.
  • Laravel's container is PSR-11 compliant, so ContainerMiddlewareResolver can be pointed at it directly — that part is clean. Attribute-based resolution, tagged middleware, and per-route middleware aliases would all need hand-rolled glue.
  • No Laravel adapter exists and there are zero dependents on Packagist, so there is no reference integration to copy or community-fixed edge cases.

Technical risk

  • Maintenance risk (primary): last release 2021-07-27, single maintainer, ~100 stars, no dependents. Treat it as effectively feature-frozen. It is small enough (a few hundred lines) to vendor or fork, but that must be an explicit decision, not a discovery.
  • Compatibility risk: PHP version floor/ceiling is unverified against PHP 8.2/8.3/8.4. A deprecated dynamic-property or nullable-parameter pattern in a 2021 codebase is plausible; a CI matrix on our target runtime is a gate, not a nicety.
  • Semantic parity risk: Laravel middleware ordering, priority lists, terminable terminate() calls, $next($request) short-circuiting, and exception-to-response mapping have no direct PSR-15 equivalent. Behavior will differ subtly, and auth/session/CSRF middleware cannot be reused across the boundary.
  • Low opportunity signal (32.2): the package differentiates little versus Illuminate\Pipeline, league/route, Laminas Stratigility, or Slim's dispatcher. We would be taking on a dependency to solve a problem Laravel already solves.

Key questions

  1. What concrete requirement forces PSR-15 — portability to a non-Laravel runtime, or reuse of third-party PSR-15 middleware? If neither, reject.
  2. What is our supported PHP range, and does the package pass tests across it?
  3. Are we prepared to own a fork (or vendor copy) with a named maintainer and upgrade budget?
  4. Do any responses rely on streaming, file downloads, or BinaryFileResponse? Bridging these through PSR-7 is where conversions break.
  5. Where does the boundary sit — one route group, one package, or the whole app? Whole-app is a rewrite, not an integration.
  6. How will auth, session, CSRF, and exception handling behave when a request crosses into the PSR-15 chain and back?

Integration Approach

Stack fit

  • Do not replace the Laravel HTTP kernel pipeline. Introduce Middleman only inside a bounded seam: a single controller or a dedicated package that exposes a PSR-15 MiddlewareInterface stack and is invoked from one Laravel route.
  • Concretely: Route::any('/psr/{path?}', PsrBridgeController::class)->where('path', '.*') → convert Illuminate\Http\Request to PSR-7 → run Middleman with our middleware list → convert PSR-7 response back to Illuminate\Http\Response.
  • Keep Laravel-native concerns (session, auth guards, CSRF, throttling, cookies, exception rendering) outside the seam, in normal Laravel middleware. Inside the seam, only transport-level and domain middleware.

Migration path

  • Phase 0 (1–2 days): spike. Wire the bridge, run three middleware, verify a JSON response, a redirect, and an error path. Verify PHP runtime compatibility and lockfile behavior.
  • Phase 1: if the spike holds, containerize the dispatcher behind a small internal interface (PsrMiddlewareRunner) so the vendor dependency is swappable for Illuminate\Pipeline or a fork without touching call sites.
  • Phase 2: migrate only the middleware that genuinely needs PSR-15 portability. Nothing in app/Http/Middleware moves.
  • Phase 3 (optional): if portability was the driver, extract the seam into a package with its own test suite; the Laravel binding becomes one adapter among several.
  • Explicit non-goal: a big-bang migration of the existing middleware stack. That path has high regression risk and near-zero payoff.

Compatibility

  • Pin an exact version; add a composer.json conflict/allowlist and an automated composer outdated + PHP matrix check so an abandoned upstream is a known state rather than a surprise.
  • Vendor or fork with a documented patch policy. Because the surface is small, a fork is cheap insurance and removes the "what if Packagist archive" question.
  • Verify PSR-7/PSR-17 implementation choice against Laravel's HTTP client and testing helpers; nyholm/psr7 is the lighter default.

Sequencing

  1. Confirm the business requirement for framework-agnostic middleware (gate).
  2. Compatibility spike on target PHP + Laravel versions.
  3. Bridge + single-route proof, including error and streaming response behavior.
  4. Internal wrapper interface, then incremental middleware adoption.
  5. Fork/vendor decision recorded in an ADR before any production exposure.

Operational Impact

Maintenance

  • Low code volume, high ownership. Expect no upstream fixes; budget a few days per year for compatibility patching, mostly around PHP minor releases and PSR-7 bridge upgrades. The real cost is the bridge, not Middleman.
  • The dependency adds a second place to look when a request misbehaves. Logging, tracing, and request IDs must be propagated across the Laravel↔PSR-7 boundary or observability splits in two.

Support

  • Community-only, single maintainer, no vendor. Internal escalation must terminate at a named engineer who owns the fork. Without that, an incident on an abandoned dependency has no path to resolution.

Scaling

  • The dispatcher itself is negligible: array iteration and delegate calls, no meaningful CPU or memory overhead at our volume.
  • The bridge is the cost center. Request/response conversion duplicates body content, which matters for large uploads and streamed downloads. Under concurrency, buffering behavior is the thing to load-test, not the dispatcher.
  • Horizontal scaling is unaffected — the library is stateless. No new infrastructure.

Failure modes

  • Response fidelity loss: streamed, chunked, or binary responses degrade or fully buffer across the bridge; headers like Content-Length, Transfer-Encoding, and Set-Cookie can be dropped or reordered.
  • Exception escape: an exception thrown inside the PSR-15 stack bypasses Laravel's handler unless the seam catches and re-throws into it; error pages and reporting silently diverge.
  • Ordering divergence: two middleware engines mean two ordering models. A Laravel middleware that assumed it ran before/after a given step may now run on the wrong side of the seam.
  • Container resolution mismatch: PSR-11 get() semantics differ from Laravel's autowiring and contextual binding; middleware depending on request-scoped bindings can resolve stale or fail.
  • Abandonment: a future PHP release breaks the package and no patch arrives; without a fork this blocks upgrades.
  • Auth/session split-brain: state mutated inside the PSR-15 stack is not automatically visible to Laravel's session or cookie jars.

Ramp-up

  • The library's API is small (MiddlewareDispatcher, MiddlewareResolver, Delegate) and can be learned in under a day by anyone comfortable with PSR-7.
  • The steeper curve is PSR-7/PSR-15 mental models for a team raised on Laravel middleware — immutability of requests/responses, explicit response returns instead of $next(), and the absence of framework conveniences. Plan a short internal walkthrough and a reference example in the repo before the first adopter outside the seam.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console