Как добавить время выполнения, необходимое для ответа API в среде Lumen, в ответе JSON

Я хотел бы добавить время, необходимое API для ответа в ответе JSON. В настоящее время разрабатывается API с фреймворком Lumen.

Если кто-то может направить с лучшим подходом. Не уверен, что мне придется использовать какие-либо хуки, предоставленные фреймворком, или просто вычислить их в файле маршрутов. И как отправить его на все ответы API.

PS: Все еще изучаю фреймворк Laravel/Lumen.

Спасибо, Танмай.


person jtanmay    schedule 13.01.2016    source источник


Ответы (3)


В вашем файле public/index.php добавьте туда константу:

<?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();

Следующий шаг — создать промежуточное ПО и включить его, чтобы мы могли манипулировать нашим ответом. Создайте промежуточное ПО в app/Http/Middleware с именем 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;
    }
}

Чтобы включить это промежуточное ПО в ваше приложение, добавьте:

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

В вашем файле bootstrap/app.php. Так что это будет так:

<?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;

Примечание. Если в вашем приложении есть другое ПО промежуточного слоя, вы можете добавить ПО промежуточного слоя MeasureExecutionTime вместо END любого другого ПО промежуточного слоя.

Для дальнейших исследований даю ссылку на документацию:

  1. Промежуточное ПО.
  2. Ответы.

ОБНОВИТЬ

Если вы не хотите добавлять прошедшее время в тело ответа, вы можете добавить его в заголовки:

<?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;
    }
}
person krisanalfa    schedule 20.01.2016
comment
Спасибо за подробное объяснение. - person jtanmay; 21.01.2016
comment
Одно замечание: вы должны добавить время отклика в качестве заголовка, например X-Response-Time. Таким образом, вы экономите время, не расшифровывая и не кодируя свой ответ. Также это работает и для других типов контента: изображений, html и т. д. - person user237329; 16.12.2016

В каталоге public у вас есть файл index.php. Создайте там переменную:

define('LUMEN_START', microtime());

Теперь в вашем контроллере вы можете просто передать параметр:

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

Он будет измерять время от запуска (public/index.php — это первый файл, запускаемый сервером) до ответа.

person Grzegorz Gajda    schedule 19.01.2016
comment
Мы должны добавить 'response_time' => microtime() - LUMEN_START в каждый ответ/контроллер. Я предпочитаю использовать Middleware в качестве глобального решения. Пожалуйста, прочитайте мой ответ ниже. - person krisanalfa; 20.01.2016
comment
для простоты это хорошо, но, вероятно, будет работать с решением промежуточного программного обеспечения, поэтому мне не нужно добавлять отдельно для каждого ответа. - person jtanmay; 21.01.2016

Я использую Lumen 5.3 и хочу вернуть JsonResponse. Из-за этого мне пришлось немного модифицировать промежуточное ПО от Alfa:

Вместо

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

я использую

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

Не уверен, связано ли это с JsonResponse или версией Laravel/Lumen, но у меня это работает.

person Lars    schedule 23.10.2016