I have a system that might have a lot of controllers in the future. What I wanted to achieve (and achieved) is to make some form of dynamic routes, in order not to flood routes/web.php file with tons of route groups (there might be more than 300 routes).
So I did this:
routes/web.php
Route::get('/report/{report_name}', [ReportController::class, 'index'])->name('report');
Route::post('/report/{report}/{method_name}', [ReportController::class, 'getRpcCall'])->name('report'); // This one used for RPC call (like Vue.js/AJAX calls)
ReportController.php:
public function index(string $reportName = null)
{
if (!class_exists(self::REPORTS_NAMESPACE . $reportName . 'Controller')) {
throw new ReportClassNotFoundException($reportName);
}
$report = app(self::REPORTS_NAMESPACE . $reportName . 'Controller');
return $report->index();
}
public function getRpcCall(Request $request, string $report = null, string $methodName = null): mixed
{
if (!class_exists(self::REPORTS_RPC_NAMESPACE . $report . 'RpcController')) {
throw new ReportClassNotFoundException($report);
}
$report = app(self::REPORTS_RPC_NAMESPACE . $report . 'RpcController');
$method = $methodName;
if (!method_exists($report, $method)) {
throw new MethodNotFoundException($report, $methodName);
}
return $report->$method($request);
}
But since I am a big fan of using FormRequests (in order not to bloat Controller with stuff that shouldn't be there, according to the SRP), I created a controller for reporting, that is being called dynamically, using above methods, like this: {{ route('rpc.report', ['FuelReporting', 'updateFuelCardData']) }}. Here it is:
class SomeReportingRpcController extends Controller
{
public function updateFuelCardData(SomeModelUpdateRequest $request): Response
{
// Some stuff going on here
}
}
As you can see, I use SomeModelUpdateRequest as a form request (created via php artisan make:request SomeModelUpdateRequest) for validation purposes. But the problem is that Laravel throws an error that
Argument #1 ($request) must be of type App\Http\Requests\SomeModelUpdateRequest, Illuminate\Http\Request given, called in ReportController.php
As I thought, that even if SomeModelUpdateRequest extends FormRequest (which extends Illuminate\Http\Request class), it should be fine, since method param type hinting is not conflicting with parent and child classes, but I was wrong.
Any ideas on how to keep the "dynamic route" logic and be able to use Form Requests?
I already have a working solution to ditch the Form request and use $request->validate() in some service class, but it is not so clean and I won't be able to use $request->validated() after that, that is kind of crucial for me.
Kind regards,