ต่อยอด Laravel Debugbar เพื่อดีบัก Rest API Routes
Tags: debugbar, tutorial, api, ไทย
Published: 2019-06-28 02:45:55

---
title: ต่อยอด Laravel Debugbar เพื่อดีบัก Rest API Routes
published: true
description: ปัญหาคือ ใช้ Debugbar เพื่อที่จะดัก load time, query string และ memory consume ใน Laravel 5.4 สำหรับ APIs Route ไม่ได้ ดังนั้นจึงสร้าง middleware สำหรับ โยนข้อมูลจาก Debugbar มาใส่ใน Api ด้วย
tags: Debugbar, tutorial, API, ไทย
cover_image: https://thepracticaldev.s3.amazonaws.com/i/gu86k23i6p4uzevad6jl.jpg
---

# ปัญหา 👹
บทความนี้เขียนจากประสบการณ์จริง โปรเจ็คที่ผมทำอยู่มีปัญหาด้านความเร็วในการตอบสนอง เพราะ endpoint บางตัวใช้เวลาในการตอบสนองนานกว่า 10s ทำให้ไม่สามารถที่จะยอมรับได้ เพราะ **ช้าเกินไปมากๆๆๆ** 😩😩😩 ถ้าเป็นคนที่ทำโปรเจ็คมาตั้งแต่ต้น การดีบักก็คงไม่มีปัญหา 

ผมลองจินตนาการดู ถ้าเราไม่ได้ทำโปรเจ็คต่อล่ะ สมมุติถ้าคนที่มาจับโปรเจ็คต่อไม่ได้มีงานแค่ตัวเดียวล่ะ เขาต้องมาเสียเวลาส่วนมากไปกับแก้ปัญหานิดๆ หน่อยๆ อย่างนั้นหรือ ดูไม่คุ้มเลย 😡

ผมเลย install package Debugbar เผื่อไว้เพื่อทีจะเอาไว้ดีบัก แต่ติดที่ว่า debugbar ไม่สามารถโชว์ผลลัพธ์ใน api route ได้ 😭😭 เอาล่ะสิต้องพึ่งพา อากู๋ หน่อยล่ะ แล้วในที่สุดหลังจากการ research ผมก็ได้มาซึ่งสิ่งที่ต้องการ 🎉🎉🎉


## Framework & Packages ⚙️

- [Laravel 5.4](https://github.com/laravel/laravel/tree/5.4)
- [Debugbar 2.4](https://github.com/barryvdh/laravel-debugbar/tree/2.4)
- [Dingo Api](https://github.com/dingo/api)

```bash
# install laravel 5.4
composer create-project --prefer-dist laravel/laravel yourProjectName "5.4.*"
# install debugbar 2.4 that compatible with laravel 5.4
composer require barryvdh/laravel-debugbar:~2.4
# install dingo/api
composer require dingo/api
```
ผมไม่ได้แสดงวิธี install ทุกขั้นตอนนะครับ เพื่อนๆ สามารถอ่านวิธีการ install และ config เบื้องต้นได้จาก link ที่ให้ไว้ได้นะครับ

## วิธีทำ 👩‍🏫

จากที่เห็น โปรเจ็คตัวนี้ใช้ laravel v5.4, debugbar v2.4 และ dingo api v1 ส่ิงที่เราต้องการคือ **การโชว์ข้อมูลจาก debugbar เมื่อเราทำการ access api route จาก browser หรือ postman**

เริ่มด้วยการสร้าง Middleware

```php
<?php

namespace App\Http\Middleware;

use Closure;
use Dingo\Api\Http\Response;

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

        if ($response instanceof Response &&
            app()->bound('debugbar') &&
            app('debugbar')->isEnabled()
        ) {
            $queries_data = $this->sqlFilter(app('debugbar')->getData());
            $response->setContent(json_decode($response->morph()->getContent(), true) + [
                '_debugbar' => [
                    'total_queries' => count($queries_data),
                    'queries' => $queries_data,
                    'time' => app('debugbar')->getData()['time'],
                    'memory' => app('debugbar')->getData()['memory'],
                ],
            ]);
        }

        return $response;
    }

    /**
     * Get only sql and each duration
     *
     * @param $debugbar_data
     * @return array
     */
    protected function sqlFilter($debugbar_data)
    {
        $result = array_get($debugbar_data, 'queries.statements');

        return array_map(function ($item) {
            return [
                'sql' => array_get($item, 'sql'),
                'duration' => array_get($item, 'duration_str'),
            ];
        }, $result);
    }
}

```

จากนั้นทำการเพิ่ม middleware `ProfileDingoHttpResponse` ที่เราเพิ่งสร้างไป ในไฟล์ `Kernel.php` ซึ่งอยู่ใน `yourProjectName/app/Http/Kernel.php`

```php
<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    ...

    protected $routeMiddleware = [
        ...
        'profile-dingo-http' => \App\Http\Middleware\ProfileDingoHttpResponse::class,
    ];
}
```

หลังจากที่เราเพิ่ม `'profile-dingo-http' => \App\Http\Middleware\ProfileDingoHttpResponse::class,` ไปใน `$routeMiddleware` จากนั้นเราก็สามารถเพิ่ม middleware ได้แล้ว โดยในโปรเจ็คนี้เราใช้ Dingo api ซึ่งจะเห็นวิธีเพิ่ม middleware ได้จากตัวอย่างด้านล่าง

```php
<?php
$api = app('Dingo\Api\Routing\Router');

$api->version('v1', ['middleware' => 'profile-dingo-http'], function ($api) {
    ...
});
```

 🎉🎉🎉 เสร็จแล้วครับ 

## ผลลัพธ์ 💯

หลังจากทำการเรียก api จาก url เราจะได้ผลลัพธ์ซึ่งเป็นข้อมูลจาก debugbar ที่เราสร้างไว้ใน Middleware `ProfileDingoHttpResponse` ห้อยท้ายมาด้วย

![](https://thepracticaldev.s3.amazonaws.com/i/fm5emewm63fbta3c25is.jpg)

นี่คือผลลัพธ์ที่ได้ห้อยท้ายเพิ่มเติมเมื่อเราเพิ่ม middleware เข้าไปครับ ถ้าหากไม่ชัดก็สามารถดูตัวอย่างจากด้านล่างได้ครับ

```json
"_debugbar": {
    "total_queries": 1,
    "queries": [
        {
            "sql": "select `id`, `name`, `description` from `product` where `id` = '2' limit 1",
            "duration": "14.01ms"
        }
    ],
    "time": {
        "start": 1561688591.7021,
        "end": 1561688591.8966,
        "duration": 0.19451189041138,
        "duration_str": "194.51ms",
        "measures": [
            {
                "label": "Booting",
                "start": 1561688591.7021,
                "relative_start": 0,
                "end": 1561688591.786,
                "relative_end": 1561688591.786,
                "duration": 0.083874940872192,
                "duration_str": "83.87ms",
                "params": [],
                "collector": null
            },
            {
                "label": "Application",
                "start": 1561688591.7738,
                "relative_start": 0.071721792221069,
                "end": 1561688591.8966,
                "relative_end": 0.0000050067901611328,
                "duration": 0.12279510498047,
                "duration_str": "122.8ms",
                "params": [],
                "collector": null
            }
        ]
    },
    "memory": {
        "peak_usage": 19660800,
        "peak_usage_str": "18.75MB"
    }
}

```

ด้วยเหตุฉนั้น เลยได้ผลลัพธ์ในแบบฉนี้ และแล้วในตอนนี้การ debug ก็จะง่ายขึ้นไม่ว่าจะสำหรับคนเก่าหรือใหม่ ซึ่งสามารถทำให้เราหาสาเหตุของสิ่งที่เราต้องการแก้หรือปรับปรุงได้ง่ายยิ่งขึ้น ขอบคุณครับ จบแล้วครับ 🥳 🥳 🥳 

#### Source & so much thanks ❤️🎉🥰

[REST API profiling #252](https://github.com/barryvdh/laravel-debugbar/issues/252)