Since I want to fire endpoints upon accept header, I created a middleware to identify which version is using the client:
// ApiVersionMiddleware public function handle($request, Closure $next) { $route = $request->route(); $actions = $route->getAction(); $actions['uses'] = str_replace( '{api}', $request->header('api-version'), $actions['uses'] ); $route->setAction($actions); return $next($request); }
I then changed the default RouteServiceProvider
namespace:
class RouteServiceProvider extends ServiceProvider { // protected $namespace = 'AppHttpControllers'; // default value protected $namespace = null; . . }
Finally, in my routes.php
file, I have:
Route::group(['middleware' => 'api-version'], function() { Route::resource('items', 'AppHttpControllers{api}ItemsController', ['only' => ['show', 'index', 'store', 'destroy']]); });
I tried to register the middleware in the HttpKernel class instead of grouping route definitions but it did not work.
I was wondering if there is a better way to achieve API versioning.
- I would like to have a
routes.php
file for each version:v1-routes.php
,v2-routes.php
and so on. - I don’t like the idea of grouping my route definitions in the
routes.php
just to get access to the{api}
value. Is any other way to find out which Controller should I fire?
Thanks.
Advertisement
Answer
I guess you can try something like this on your routes.php I haven’t tested but should work
switch (Request::header('api-version')) { case 'v2': include_once('routes_v2.php'); break; default: include_once('routes_v1.php'); }
And in the route_v….php files define the routes as you would do normally.
UPDATE
The correct way to do this would be in the RouteServiceProvider’s map function. You will have just two route files.
You can easily manage multiple versions of apis in the dingo/api package. It will save a lot of time for you.