liip/multiplex-bundle
LiipMultiplexBundle lets a Symfony project serve multiple applications or websites from one codebase, routing requests by host or configuration so each app can keep separate settings and templates while sharing common logic.
Architecture fit: none as code, high as precedent. The package targets the Symfony 2.x kernel/bundle extension model — services registered into a Symfony DI container, listeners on kernel.request, sub-request dispatch through HttpKernelInterface::handle(). There is no Laravel extension contract for this. The only TPM-relevant fit is conceptual: it is a documented, small prior-art implementation of server-side API composition and uniform JSON coercion, both of which are recurring asks in any Laravel product roadmap. Evaluate it as a design reference, not a component.
Integration feasibility: zero as a dependency. Archived, deprecated, ~12 stars, zero Packagist dependents, no maintainer. Its Composer constraints will pin Symfony 2.x, which collides with the Symfony 6.x/7.x ranges modern illuminate/* components require — composer require fails at resolution, and no Laravel kernel would boot the bundle even if forced. There is no integration story, only a read-and-reimplement story.
Technical risk: severe if adopted, contained if cited. Symfony 2.8 hit EOL in November 2018. Any transitive dependency inherits an unpatched CVE tail across HttpFoundation, Serializer, YAML, and polyfills, plus PHP 5.x/7.0-era syntax with no typed properties or strict typing. There is no trustworthy test suite against modern PHP and no CI. For a TPM the risk framing is simpler than the engineering detail: adopting this means shipping unsupported code on the hot path of every aggregated request, with no security patch channel and a bus-factor of one — whoever read the source.
What is actually salvageable — the two design ideas. (1) Multiplexing: one inbound request carries N sub-request descriptors (id, method, URI, params), the server dispatches them, and returns a composed payload with per-item status codes so partial failure is representable. This remains the cleanest known shape for the "mobile screen makes 8 calls and feels slow" problem. (2) Uniform JSON-ification: a listener coercing any controller return into a JSON envelope, decoupling handler output shape from transport serialization. Laravel already solves (2) natively with JsonResource, Responsable, and response middleware; only (1) is worth a decision.
Key product/technical questions to put to the team.
/batch endpoint.Http::pool() is the safer default.Verdict. The package is not a candidate; the pattern is. Record the decision explicitly so the next engineer who rediscovers the repository does not re-run this evaluation.
Stack fit: concept-only. The deliverable from this evaluation is a short design note and a native Laravel implementation, not a Composer entry. Map the bundle's two ideas onto primitives the stack already ships:
| Need | Laravel-native mechanism |
|---|---|
| Concurrent fan-out to downstream HTTP services | Http::pool() / Illuminate\Http\Client\Pool, with per-request error capture |
| Internal sub-request handling | Prefer restructuring as service calls; kernel re-entry is possible but fragile |
| Uniform JSON envelope | JsonResource, Responsable, or response middleware |
| Versioned batch contract | Dedicated /api/v1/batch controller + FormRequest validation of the descriptor array |
| Growing composition surface | GraphQL (Lighthouse) or client-side parallel calls over HTTP/2 if compositions change often |
Migration path: there is none — this is a greenfield build with a borrowed schema. The only artifact worth porting is the request/response envelope. Sequence it as its own story:
/batch with Http::pool() against real downstream services. Measure aggregate latency versus N sequential calls and confirm concurrency limits hold under the PHP-FPM pool you actually run.{id, method, path, body}; response envelope {results: [{id, status, body}]} with per-item status codes. This is precisely the part the old bundle got right.Compatibility. None at the Composer level. Installing alongside Laravel 9/10/11 fails on Symfony constraint resolution; in isolation the code targets a kernel and container API that no longer exists. Assume zero upstream fixes for PHP 8.3/8.4 deprecations, forever.
Sequencing recommendation. Do not place this package on the roadmap in any form — not even as a "phase 0." If batching is a genuine requirement, sequence the native build above as a single, time-boxed story (roughly 1–2 days for a minimal version plus whatever the partial-failure and timeout contract demands). If batching is not on the roadmap, close the evaluation, write the decision record, and move on. Do not sequence "evaluate further."
Maintenance: zero upstream, unbounded ownership. Archived plus deprecated plus no dependents means no security advisories, no PHP-version compatibility work, no issue triage, no one to ask. Any fork becomes a permanent internal fork carrying full ownership cost — and you would be forking dead code to rebuild something Laravel's HTTP client and JSON resources already provide.
Support and ramp-up. No community, no documentation beyond a stale README, no Stack Overflow corpus, no vendor relationship. Institutional knowledge would live entirely with whoever read the source; their departure is an unmitigated bus-factor risk on a component sitting in the request path of every batched call. Conversely, the native replacement is standard Laravel — any mid-level engineer on the team can maintain it, and the pattern is documented publicly. Ramp-up on the build is measured in hours, not weeks.
Scaling: multiplexing relocates load, it does not remove it. A batch endpoint concentrates N downstream calls into one PHP worker. Under concurrency this inverts the normal capacity model — a handful of batch clients can saturate both the FPM pool and the downstream dependencies at once. Internal sub-request dispatch is worse: nested kernel handling multiplies memory and middleware execution per inbound request. Capacity mitigations (hard caps on N, pool concurrency limits, queue-offload for slow fan-outs) must be designed in at spec time, not bolted on after the first incident.
Failure modes to specify in the contract before building.
Bottom line for the TPM. Low effort, low risk if implemented natively, real but modest upside — and zero reason to take the dependency. The value of this package to the program is a validated envelope design and a documented "we already evaluated this and chose X" decision. Fund 1–2 days of spike work only if the aggregation requirement is genuinely prioritized; otherwise close it.
How can I help you explore Laravel packages today?