Certainly! Laravel automatically parses the JSON body of requests when the Content-Type is application/json. If that JSON is invalid, Laravel sets the request data to an empty array (i.e., null as you've discovered), but does not surface a validation or parse error by default.
To automatically return a useful error when invalid JSON is POSTed, you can create a middleware that runs before your FormRequest. This middleware validates the raw input, and aborts with a relevant error if parsing fails.
Here's how you can do it:
1. Create a Middleware
Generate a middleware called EnsureValidJson.
php artisan make:middleware EnsureValidJson
Edit the generated middleware (app/Http/Middleware/EnsureValidJson.php) as follows:
<?php
namespace App\Http\Middleware;
use Closure;
class EnsureValidJson
{
public function handle($request, Closure $next)
{
// Only check for JSON when the Content-Type is application/json
if (
str_starts_with($request->header('Content-Type'), 'application/json') &&
$request->getContent()
) {
// Try to decode raw input
json_decode($request->getContent());
if (json_last_error() !== JSON_ERROR_NONE) {
return response()->json([
'message' => 'Invalid JSON: ' . json_last_error_msg(),
], 422);
}
}
return $next($request);
}
}
2. Register the Middleware
Add your middleware to either the api middleware group (recommended for APIs) or assign it specifically to your routes in app/Http/Kernel.php:
protected $middlewareGroups = [
'api' => [
// ...existing API middleware
\App\Http\Middleware\EnsureValidJson::class,
],
];
Or use it per route/controller if you only want specific endpoints to check:
Route::post('/your-endpoint', 'YourController@store')->middleware('ensure.valid.json');
(Don't forget to add an alias if using per-route; see Kernel.php's $routeMiddleware array.)
3. Result
Now, when an invalid JSON body is submitted, the middleware will intercept before your FormRequest runs, and the client will receive a nice 422 response like:
{
"message": "Invalid JSON: Syntax error"
}
Summary:
A middleware checking the raw request content for valid JSON is the safest and most "Laravel way" to surface parse errors before your FormRequest runs. This approach works cleanly and provides developers/clients with meaningful feedback on malformed JSON.