- What does michael-rubel/laravel-safe-request actually do?
- It is an opt-in trait for Laravel FormRequest classes that makes validated input the default accessor surface, so keys are retrieved from $request->safe() rather than the raw request bag. You define rules as usual and the validator still runs exactly as before; the package only changes what the validator's output is allowed to influence. The goal is to keep unvalidated fields out of controllers and services, reducing mass-assignment and untrusted-data risk. It does not replace the validator and requires no service provider, config file, or middleware.
- How do I install laravel-safe-request in a Laravel app?
- Run composer require michael-rubel/laravel-safe-request and then add the SafeRequest trait to the FormRequest classes where you want the behavior. There is nothing to register in a service provider and no config file to publish, so the integration is a single Composer line plus a use statement. Because it is applied per request class, you can adopt it incrementally rather than across the whole application. The 2.0.1 release explicitly adds Laravel 10 support, which is what makes that path viable on current Laravel 10 projects.
- Which Laravel versions does laravel-safe-request support?
- The 2.0.1 release explicitly added Laravel 10 support, and earlier releases targeted Laravel 9. Laravel 11 and 12 are not addressed, so expect to widen the illuminate constraints yourself or fork when you upgrade past Laravel 10. Because the compatibility bump shipped as a patch version, read composer.json for 2.0.1 and confirm it widened to something like ^9.0|^10.0 rather than dropping ^9.0, and check whether the PHP constraint moved in step. Narrowing a constraint in a patch release would be a semver violation and a signal about release hygiene.
- Which request methods does the trait override?
- The package's stated behavior is that validated input becomes the default, but the exact override list is the thing you must verify in the trait source before relying on it. Check whether it touches only all(), or also input(), only(), get(), __get(), and merge(), because each addition silently changes what existing code paths see. This list is not documented in detail, and no changelog entry is not evidence that it stayed the same between 2.0.0 and 2.0.1. Read the diff and treat any change to the override list or its return semantics as a behavioral change regardless of version number.
- Does it break $request->file(), route parameters, or values added with merge()?
- It can, and this is the dominant risk of the package. Code paths that legitimately read fields absent from the rules array, such as file uploads, values injected via merge() or middleware, and route or query parameters accessed through the same request object, may start returning null instead of data. These failures are quiet rather than loud, so nothing throws and the bug surfaces downstream. Write feature tests for uploads, route parameters, and merge() usage before rolling it out to existing request classes.
- How does it behave with wildcard, sometimes, and nested validation rules?
- Access goes through the validated data set, so nested and optional keys, wildcard rules, and sometimes rules are exactly where narrowing surprises appear. A key that is valid but conditionally absent may not be present in the safe payload, and nested structures only appear as deeply as the rules describe them. The documented behavioral surface is small, so do not assume parity with the raw request. Add tests that assert the exact shape returned for each of these rule types in your specific form requests.
- Do I need a service provider or config file for laravel-safe-request?
- No. The package is additive and opt-in per request class via a trait, with no service provider, config, or middleware required. That keeps the integration footprint tiny and makes it easy to evaluate or remove later. It also means there is no central place to disable the behavior globally, so adoption and rollback both happen trait by trait in your FormRequest classes.
- How does it differ from calling $request->validated() manually?
- Calling validated() is a per-call-site decision that returns an array, while this package changes the default accessor surface of the whole request object. That is stronger and safer by default, but it also affects any code that receives the request and reads fields outside the rules. If your codebase already consistently calls validated() or maps into a DTO, the marginal benefit is smaller. The package is best suited to teams that want the safe behavior enforced structurally rather than by convention.
- Is laravel-safe-request safe to depend on in production?
- It is alive but uncommitted: a release landed after a gap of roughly two and a half years, the project is still single maintainer with no dependents and a low star count. One compatibility bump after a long dormancy is a signal of low cadence, not of an active security-response capability. The lifecycle risk is moderate rather than high now that Laravel 10 resolves, but plan for the next Laravel major to require a fork. Pin the version and keep the trait's surface small so an in-house replacement stays cheap.
- Should I use this package or write my own safe request trait?
- Reimplementation cost is near zero, roughly a dozen lines in an in-house trait, so build versus buy is a close call. Buying costs one Composer line on Laravel 10 instead of an immediate fork, which is genuinely cheaper, until the next Laravel major when you fork anyway. If you already use validated() consistently or map validated data into DTOs, an in-house trait or explicit validated() calls give you the same guarantee with full control over the override list. Choose the package if you want the behavior now with minimal effort and are comfortable reading the source to confirm semantics.