Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Api versioning in laravel: routing depending on the "Accept" Header

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 = 'App\Http\Controllers'; // default value
    protected $namespace = null;
        .
        .     
}

Finally, in my routes.php file, I have:

Route::group(['middleware' => 'api-version'], function()
{
    Route::resource('items', 'App\Http\Controllers\{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.

like image 582
leamasuero Avatar asked Mar 06 '15 13:03

leamasuero


1 Answers

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.

like image 67
astroanu Avatar answered Nov 04 '22 02:11

astroanu