Laravel API Versioning with API Key in Simple Method

Hello, in this guide, I’m going to show the simple way to make API versions in Laravel.

Table of Contents

  1. Create Custom API Files
  2. Map Custom API Routes
  3. Create Controllers
  4. Define Custom Routes
  5. Test the API Routes
  6. Protect with API Key

Step 1 : Create Custom API Files

Go to the routes folder of your project. Let’s create two files called:

  • routes/api_v1.php
  • routes/api_v2.php

Step 2 : Map Custom API Routes

Open RouteServiceProvider from app>Providers folder. At the end of the file, we’ll add two functions named mapApiV2Routes() and mapApiV2Routes(). Let’s create the two functions. I’ve set custom prefix for the two API routes.

RouteServiceProvider.php
/**
 * Define the "api/v1" routes for the application.
 *
 * These routes are typically stateless.
 *
 * @return void
 */
protected function mapApiV1Routes()
{
    Route::prefix('api/v1')
        ->middleware('api')
        ->namespace($this->namespace)
        ->group(base_path('routes/api_v1.php'));
}


/**
 * Define the "api/v2" routes for the application.
 *
 * These routes are typically stateless.
 *
 * @return void
 */
protected function mapApiV2Routes()
{
    Route::prefix('api/v2')
        ->middleware(['api'])
        ->namespace($this->namespace)
        ->group(base_path('routes/api_v2.php'));
}

Now we have to define the custom API routes in the map() function of the same file. Let’s do that:

RouteServiceProvider.php
/**
 * Define the routes for the application.
 *
 * @return void
 */
public function map()
{
    $this->mapApiRoutes();

    $this->mapWebRoutes();

    // custom API routes
    $this->mapApiV1Routes();
    $this->mapApiV2Routes();
}

Step 3 : Create Controllers

At this step, we will create two controllers for the two API versions. Run these artisan commands to make the controllers:

// for API v1
php artisan make:controller API\v1\WelcomeController

// for API v2
php artisan make:controller API\v2\WelcomeController

Open the controllers and make a simple index() function like this:

API\v1\WelcomeController.php
class WelcomeController extends Controller
{
    public function index()
    {
        $response = [
            'success' => true,
            'message' => "Welcome to API version 1",
        ];

        return response()->json($response, 200);
    }
}
API\v2\WelcomeController.php
class WelcomeController extends Controller
{
    public function index()
    {
        $response = [
            'success' => true,
            'message' => "Welcome to API version 2",
        ];

        return response()->json($response, 200);
    }
}

We are about to finish. We need to define routes to test the API versions.

Step 4 : Define Custom Routes

First, let’s create a route for API version 1. Open api_v1.php from routes folder and make a route like this:

routes\api_v1.php
<?php
Route::get('welcome', 'API\v1\WelcomeController@index');

Let’s do the same thing for API version 2. Open api_v2.php and define route:

routes\api_v2.php
<?php
Route::get('welcome', 'API\v2\WelcomeController@index');

Step 5 : Test the API Routes

Our API versions are ready to use. Let’s run the project and visit the welcome routes to see the output. I’m using custom localhost domain. Please replace laravel.dev with your URL.

Version 1 URL: https://laravel.dev/api/v1/welcome

Version 2 URL: https://laravel.dev/api/v2/welcome

Step 6 : Protect with API Key

We have already done with API versioning. This step is optional. If you want to set security then you can follow this step.

We need to make a middleware. Let’s create a middle called VerifyAPIKey using this command:

php artisan make:middleware VerifyAPIKey

Open the VerifyAPIKey middleware from app\Http\Middleware and paste this code:

VerifyAPIKey.php
<?php

namespace App\Http\Middleware;

use Closure;

class VerifyAPIKey
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // You can check API key database too
        // $generate_api_key = bin2hex(openssl_random_pseudo_bytes(8));
        $api_keys = array('44b48f2305bf2680', 'a40d97bfc2ab0e56');

        if ($request->header('Authorization')) {
            $api_key = $request->header('Authorization');

            // check token
            if (in_array($api_key, $api_keys)) {
                return $next($request);
            } else {
                return response()->json([
                    'results' => 'API key is not valid',
                ]);
            }
        }

        return response()->json([
            'results' => 'Authorization failed',
        ]);
    }
}

Now open Kernel.php from app\Http and add the newly created VerifyAPIKey middleware to $routeMiddleware array:

Kernel.php
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    'VerifyAPIKey' => \App\Http\Middleware\VerifyAPIKey::class,
];

We have created a new middle and ready to use.

To protect API routes, just wrap the routes with the VerifyAPIKey middleware like this:

routes\api_v1.php
<?php

Route::group(['middleware' => 'VerifyAPIKey'], function () {
    Route::get('welcome', 'API\v1\WelcomeController@index');
});

Now pass the API key with header Authorization. Here’s the final result:

We have successfully created the API versions with API key protection. You can download this project from Gitub. Thank you.