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

Laravel Dry Requests Laravel Package

dive-be/laravel-dry-requests

Laravel Dry Requests lets your frontend validate input against the same Laravel FormRequest rules without running controller logic. Send a dry-run request, get validation results, and keep frontend and backend validation in sync with zero duplicated rules.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require dive-be/laravel-dry-requests

Laravel's package auto-discovery registers the service provider; if you need to reason about it, check vendor/dive-be/laravel-dry-requests/src for the middleware class and any config stub before wiring it in.

Register the package middleware so it can intercept requests early:

// app/Http/Kernel.php (Laravel ≤10)
protected $middleware = [
    \Dive\DryRequests\Http\Middleware\HandleDryRequests::class,
];

Then hit any endpoint that is backed by a FormRequest with the dry-run header:

curl -X POST https://app.test/api/posts \
  -H "X-Dry-Run: true" \
  -H "Accept: application/json" \
  -d '{"title": ""}'
  • 204 No Content → validation would have passed, and the controller was not executed.
  • 422 Unprocessable Entity → the normal validation error payload is returned.
  • 403 → authorize() failed (it still runs).

The first real use case is a frontend that wants to tell a user "this form is valid" without persisting anything — the middleware short-circuits after validation instead of invoking the controller.

Implementation Patterns

SPA/mobile pre-flight validation. Add the middleware to the API route group your frontend already calls, then have Axios/fetch send X-Dry-Run: true on blur or before submit. You reuse the exact rules() and authorize() logic from the real endpoint, so the client never drifts from the server's rules.

Feature-test helper. Wrap it in a test trait so validation can be asserted independently of controller behaviour:

public function assertValidationPasses(string $uri, array $data): void
{
    $this->withHeader('X-Dry-Run', 'true')
        ->postJson($uri, $data)
        ->assertNoContent();
}

Multi-step wizards. Validate step 2 against a payload the user has not yet submitted by dry-running the final "store" endpoint. Because nothing is written and no events/jobs fire, this is safe to call repeatedly.

Conditional middleware. Guard against production exposure — either scope the middleware to specific route groups or register it conditionally in a service provider:

if (! app()->isProduction()) {
    $kernel->pushMiddleware(HandleDryRequests::class);
}

Pair with stopOnFirstFailure() / after() hooks. Whatever validation behaviour the FormRequest defines is what the dry run exercises, so keep the rules and hooks on the request class rather than duplicated in controllers.

Gotchas and Tips

  • Archived package. Last release May 2023, so Composer constraints likely stop at Laravel 10 / PHP 8.1–8.2. On Laravel 11+ you will either need "minimum-stability"/ignore-platform-req gymnastics or a small fork updating the service provider. Budget for that before adopting.
  • Only FormRequest validation is intercepted. Inline $request->validate([...]) inside a controller never runs during a dry request — you'll get a false 204. Move rules into a FormRequest if you want dry-run coverage.
  • Middleware ordering matters. Place it after SubstituteBindings (and after auth middleware) so route-model binding and authorize() see the same route parameters they would in a real request. Conversely, anything before it — throttling, tenancy resolution, session start — still executes, so counters and side effects are not fully avoided.
  • authorize() runs. A dry run is not a bypass; users without permission get 403, and authorization policies run against bound models.
  • Route model binding still queries the DB. A dry request to /posts/{post} will resolve the model. That is usually fine, but it means a dry run is not free.
  • CSRF for web routes. If the endpoint is a web route, the dry request needs a valid token; either use the JSON API group or exclude the dry-run route from VerifyCsrfToken (only if you accept the tradeoff).
  • Header name and config. If a request is unexpectedly executing the controller, confirm the header spelling matches what the middleware expects, publish/check the config stub, and remember headers are case-insensitive in HTTP but not always in hand-rolled test arrays.
  • Debugging. php artisan route:list -v shows which middleware is attached to a route; a quick dd() inside the middleware's handle() confirms whether it is being reached before the controller.
  • Frontend contract. Treat 204 as "valid" and parse 422 with the standard Laravel error envelope (errors), so existing form-error components work unchanged.
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.
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
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource