Я занимаюсь созданием Restful API в Laravel 5.1, где версия API передается через заголовок. Таким образом, я могу модифицировать функции, а не копировать и вставлять всю группу маршрутов и увеличивать номер версии.
Проблема, с которой я сталкиваюсь, заключается в том, что я хотел бы иметь версии методов, IE:
public function store_v1 (){ }
Я добавил промежуточное программное обеспечение на своих маршрутах, где я беру версию из заголовка, но теперь мне нужно изменить запрос, чтобы выбрать правильный метод с контроллера.
приложение / Http / routes.php
Route::group(['middleware' => ['apiversion']], function() { Route::post('demo', 'DemoController@store'); }
приложение / Http / Промежуточный / ApiVersionMiddleware.php
public function handle($request, Closure $next) { $action = app()->router->getCurrentRoute()->getActionName(); // dd($action) // returns "App\Http\Controllers\DemoController@store" }
Отсюда я приложил бы версию заголовка к $ action, а затем передал бы ее через $ request, чтобы достигнуть правильного метода.
Ну, это и есть теория.
Любые идеи о том, как я буду вводить действия в маршрут?
Я думаю, что Middleware может быть не лучшим местом для этого. У вас есть доступ к маршруту, но он не предлагает изменить способ контроллера, который будет вызываться.
Более простой вариант – зарегистрировать настраиваемый диспетчер маршрутов, который обрабатывает логику вызова методов контроллера на основе запроса и маршрута. Это может выглядеть так:
<?php class VersionedRouteDispatcher extends Illuminate\Routing\ControllerDispatcher { public function dispatch(Route $route, Request $request, $controller, $method) { $version = $request->headers->get('version', 'v1'); // take version from the header $method = sprintf('%s_%s', $method, $version); // create target method name return parent::dispatch($route, $request, $controller, $method); // run parent logic with altered method name } }
После того, как у вас есть этот пользовательский диспетчер, зарегистрируйте его в AppServiceProvider:
public function register() { $this->app->singleton('illuminate.route.dispatcher', VersionedRouteDispatcher::class); }
Таким образом, вы перезапишите диспетчера маршрутов по умолчанию с вашим собственным, который будет суффикс имени метода контроллера с версией, взятой из заголовка запроса.