silarhi/rest-upload-bundle
A Symfony bundle for adding RESTful file-upload endpoints to your application. It streamlines receiving, storing, and managing uploaded files through a simple API, reducing boilerplate for upload workflows.
Architecture fit — the framing is wrong before we start. silarhi/rest-upload-bundle is a Symfony bundle, not a Laravel package. Its value is delivered through Symfony's extension model: a DependencyInjection\*Extension compiling a Configuration tree, kernel bundle registration in config/bundles.php, and event-dispatcher/listener hooks into the HTTP kernel. Laravel has no bundle autodiscovery, no config-tree compilation, and no kernel bundle registry. There is no ServiceProvider, no publishable config/rest-upload.php, no facade. What is portable is the domain logic — content-type-based handler dispatch, base64-JSON-to-UploadedFile transformation, chunk reassembly, size/MIME validation, filesystem persistence. That is a pattern, not a package. Since the wiring is most of what a bundle is, the honest read is: we are evaluating a design spec with an implementation attached to someone else's framework.
Integration feasibility. Three paths exist; only one is defensible for a Laravel codebase:
symfony/http-foundation transitively, but bootstrapping a bundle extension inside Illuminate's container is unsupported and brittle. Rejected.ServiceProvider + config file + middleware. Roughly 3–5 engineer-days for a thin port, plus permanent fork ownership and a private Composer/VCS entry.UploadHandler interface with per-format strategies, a FormRequest for validation, Flysystem disks for storage, queued jobs for chunk assembly. Roughly 1–2 engineer-days if the supported modes are simple. Recommended.If a genuine Symfony service ever needs this capability, path 3 still wins (the pattern is a few hundred lines), with path 2 as the fallback for a legacy Symfony app that must not be touched.
Technical risk — high, and predominantly provenance risk. Zero stars, zero dependents, composite score 0, opportunity score 22.28. That is the profile of a dormant personal project, not a maintained dependency. Consequences: no community security review, no CVE response surface, unknown test coverage or CI status, single-maintainer bus factor, and no compatibility guarantee against current PHP 8.x / Symfony 6–7. Upload endpoints are among the highest-risk attack surfaces an API exposes — path traversal, unsafe filename handling, content-type spoofing, zip-slip and decompression bombs, memory exhaustion on large or base64 payloads, orphaned temp files, and SSRF if remote-URL ingestion is supported. Putting an unvetted handler on that surface is a bad trade regardless of feature value, and the feature value here is small.
Key questions before any decision:
multipart/form-data, base64-in-JSON, raw binary, chunked/resumable, remote-URL fetch? Remote fetch alone triggers an SSRF review.move()) or delegate to a storage abstraction (Flysystem/S3)? Self-persistence to local disk is a horizontal-scaling blocker.Verdict: do not adopt as a runtime dependency. Use it as a reference implementation, and only after reading the core classes.
Stack fit. Laravel services should not host Symfony bundles in-process. The transitive symfony/http-foundation dependency means we already share UploadedFile semantics, but nothing in the bundle's registration path has a Laravel analogue. Mixing frameworks in one runtime creates a second, undocumented container contract that every future engineer must learn to debug a file upload — a permanent tax on a narrow feature.
Migration path. Read the source, write a one-page behavior specification (supported modes, size and chunk limits, filename sanitization rules, error response shapes, storage outcomes), then implement that spec behind a new UploadHandler interface with one strategy per content type, registered in a service provider and selected by a middleware or controller. Existing upload endpoints keep working untouched until we flip a per-route flag.
Compatibility. Before committing to any path, run a Composer dry-run in a throwaway branch and specifically check symfony/http-foundation and symfony/config pins against what Illuminate requires. If the bundle needs a newer Symfony major than Laravel pins, path 2 turns into a fork-with-downgrade exercise and the estimate rises materially. Also confirm PHP 8.2/8.3 support — a bundle with no recent commits frequently fails here.
Sequencing.
composer install and the test suite, read the handler-dispatch and file-factory classes, produce the behavior spec and a one-page build-vs-adopt recommendation. This is the decision gate; do not proceed past it without the spec.UploadHandler abstraction and config surface behind a feature flag, with zero behavior change to current endpoints. Add edge-level max-body-size limits at the same time.If a hard requirement exists to reuse the bundle verbatim, the only clean option is an isolated Symfony microservice behind an internal endpoint — an extra network hop, a second runtime, and a second deploy pipeline for a feature this narrow. Not justified.
Maintenance. Upstream is effectively unmaintained, so any adoption means we own the code from day one. That means a private fork or vendored copy, an entry in the internal patching cadence, dependency-update chores on every PHP/Symfony bump, and a named owner in the service catalog. Native reimplementation in our own idioms eliminates the liability entirely and is cheaper than the fork over any horizon longer than about two quarters.
Support. No vendor, no SLA, no forum, no dependent projects to consult. The escalation path is "read the source." Acceptable for a 200-line utility; unacceptable for a security-sensitive upload path unless we have already reviewed and forked it ourselves.
Scaling. Upload handling is I/O- and memory-bound, and the naive patterns here do not scale horizontally. Base64 payloads inflate memory roughly 33% over the decoded size before validation runs. Chunked assembly needs shared temp storage (S3 multipart or a shared volume) or sticky sessions to work across pods. The durable architecture is presigned direct-to-object-storage uploads where the API only issues credentials and records metadata — a bundle that accepts and persists files server-side does not help us get there and would be obsolete on arrival.
Failure modes to instrument for: orphaned partial chunks consuming disk; temp-file leakage on aborted requests; memory exhaustion on large or base64 payloads; gateway timeouts on slow multipart posts; path traversal via crafted filenames; content-type spoofing with no server-side magic-byte check; duplicate submissions without idempotency keys; and silent success responses for files that never reached durable storage. Mitigations: hard max-size limits at the edge/proxy, a temp-file reaper cron, mandatory MIME allow-list plus magic-byte verification, idempotency keys on the endpoint, malware scanning between receipt and persistence, and a metric on "upload accepted vs. object present in bucket."
Ramp-up. Code volume is small; context-switching cost is not. A Laravel team needs one to two days to internalize Symfony bundle conventions (kernel registration, Configuration trees, Extension::load) before the spike produces a trustworthy judgment — and that knowledge decays immediately if it is used once. Once ported to native Laravel patterns, ongoing cognitive load drops to near zero and the team stays inside one mental model. That asymmetry — trivial feature, disproportionate framework friction, zero ecosystem signal — is the whole argument. Recommendation to stakeholders: skip the dependency, harvest the pattern, budget 1–2 engineer-days, and put the format-support decision (multipart, base64-JSON, raw binary, chunked) on the roadmap as a product choice with a documented support obligation per format.
How can I help you explore Laravel packages today?