Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add execution time taken for an API to respond in Lumen framework in the JSON response

Tags:

laravel

lumen

I would like to add the time taken by the API to respond in the response JSON. Currently developing API with Lumen framework.

If anyone can guide with best approach. Not sure if I would have to use any Hooks provided by framework, or just calculate them in routes file. And how to push it to all the API responses.

PS: Still learning Laravel/Lumen framework.

Thanks, Tanmay

like image 348
jtanmay Avatar asked Jan 13 '16 22:01

jtanmay


People also ask

Does Lumen have eloquent?

Of course, you may easily use the full Eloquent ORM with Lumen. To learn how to use Eloquent, check out the full Laravel documentation.

Should I use Lumen or Laravel?

Laravel is easy to understand and robust MVC framework for web application development in PHP. Lumen is a micro framework that means smaller, simpler, leaner, and faster; Lumen is primarily used to build for microservices with loosely coupled components that reduce complexity and enhance the improvements easily.

How fast is Laravel Lumen?

To be precise, Lumen handles 100 requests per second. So, if speed is your requirement, then you know which framework to choose.


2 Answers

In your public/index.php file, add a constant there:

<?php

/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| First we need to get an application instance. This creates an instance
| of the application / container and bootstraps the application so it
| is ready to receive HTTP / Console requests from the environment.
|
*/

// To calculate your app execution time
define('LUMEN_START', microtime(true));

$app = require __DIR__.'/../bootstrap/app.php';

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/

$app->run();

The next step is create a middleware and enable it so we can manipulate our response. Create a middleware in app/Http/Middleware with name MeasureExecutionTime.php.

<?php

namespace App\Http\Middleware;

use Closure;

class MeasureExecutionTime
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Get the response
        $response = $next($request);

        // Calculate execution time
        $executionTime = microtime() - LUMEN_START;

        // I assume you're using valid json in your responses
        // Then I manipulate them below
        $content = json_decode($response->getContent(), true) + [
            'execution_time' => $executionTime,
        ];

        // Change the content of your response
        $response->setContent($content);

        // Return the response
        return $response;
    }
}

To enable this middleware in your application, add:

$app->middleware([
   App\Http\Middleware\MeasureExecutionTime::class
]);

In your bootstrap/app.php file. So it would be like this:

<?php

require_once __DIR__.'/../vendor/autoload.php';

try {
    (new Dotenv\Dotenv(__DIR__.'/../'))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    // n00p
}

/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| Here we will load the environment and create the application instance
| that serves as the central piece of this framework. We'll use this
| application as an "IoC" container and router for this framework.
|
*/

$app = new Laravel\Lumen\Application(
    realpath(__DIR__.'/../')
);

// $app->withFacades();

// $app->withEloquent();

/*
|--------------------------------------------------------------------------
| Register Container Bindings
|--------------------------------------------------------------------------
|
| Now we will register a few bindings in the service container. We will
| register the exception handler and the console kernel. You may add
| your own bindings here if you like or you can make another file.
|
*/

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

/*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/

$app->middleware([
   App\Http\Middleware\MeasureExecutionTime::class
]);

// $app->middleware([
//    App\Http\Middleware\ExampleMiddleware::class
// ]);

// $app->routeMiddleware([
//     'auth' => App\Http\Middleware\Authenticate::class,
// ]);

/*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/

// $app->register(App\Providers\AppServiceProvider::class);
// $app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);

/*
|--------------------------------------------------------------------------
| Load The Application Routes
|--------------------------------------------------------------------------
|
| Next we will include the routes file so that they can all be added to
| the application. This will provide all of the URLs the application
| can respond to, as well as the controllers that may handle them.
|
*/

$app->group(['namespace' => 'App\Http\Controllers'], function ($app) {
    require __DIR__.'/../app/Http/routes.php';
});

return $app;

Note If there are another middlewares in your application, you may add MeasureExecutionTime middleware at the END of any other middlewares.

For further research I give you a link to documentation:

  1. Middleware.
  2. Responses.

UPDATE

If you don't want to add elapsed time to your response body, you can add it to the headers:

<?php

namespace App\Http\Middleware;

use Closure;

class MeasureExecutionTime
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('X-Elapsed-Time', microtime(true) - LUMEN_START);

        return $response;
    }
}
like image 138
krisanalfa Avatar answered Oct 13 '22 19:10

krisanalfa


In directory public you have file index.php. Create there a variable:

define('LUMEN_START', microtime());

Now in your controller, you can just pass a parameter:

return [
    'response_time' => microtime() - LUMEN_START
];

It will be measuring time from start (public/index.php is the first file run by server) to the response.

like image 45
Grzegorz Gajda Avatar answered Oct 13 '22 19:10

Grzegorz Gajda