Atthaphon Urairat
Posted on June 28, 2019
ปัญหา 👹
บทความนี้เขียนจากประสบการณ์จริง โปรเจ็คที่ผมทำอยู่มีปัญหาด้านความเร็วในการตอบสนอง เพราะ endpoint บางตัวใช้เวลาในการตอบสนองนานกว่า 10s ทำให้ไม่สามารถที่จะยอมรับได้ เพราะ ช้าเกินไปมากๆๆๆ 😩😩😩 ถ้าเป็นคนที่ทำโปรเจ็คมาตั้งแต่ต้น การดีบักก็คงไม่มีปัญหา
ผมลองจินตนาการดู ถ้าเราไม่ได้ทำโปรเจ็คต่อล่ะ สมมุติถ้าคนที่มาจับโปรเจ็คต่อไม่ได้มีงานแค่ตัวเดียวล่ะ เขาต้องมาเสียเวลาส่วนมากไปกับแก้ปัญหานิดๆ หน่อยๆ อย่างนั้นหรือ ดูไม่คุ้มเลย 😡
ผมเลย install package Debugbar เผื่อไว้เพื่อทีจะเอาไว้ดีบัก แต่ติดที่ว่า debugbar ไม่สามารถโชว์ผลลัพธ์ใน api route ได้ 😭😭 เอาล่ะสิต้องพึ่งพา อากู๋ หน่อยล่ะ แล้วในที่สุดหลังจากการ research ผมก็ได้มาซึ่งสิ่งที่ต้องการ 🎉🎉🎉
Framework & Packages ⚙️
# 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
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
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
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', ['middleware' => 'profile-dingo-http'], function ($api) {
...
});
🎉🎉🎉 เสร็จแล้วครับ
ผลลัพธ์ 💯
หลังจากทำการเรียก api จาก url เราจะได้ผลลัพธ์ซึ่งเป็นข้อมูลจาก debugbar ที่เราสร้างไว้ใน Middleware ProfileDingoHttpResponse
ห้อยท้ายมาด้วย
นี่คือผลลัพธ์ที่ได้ห้อยท้ายเพิ่มเติมเมื่อเราเพิ่ม middleware เข้าไปครับ ถ้าหากไม่ชัดก็สามารถดูตัวอย่างจากด้านล่างได้ครับ
"_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 ❤️🎉🥰
Posted on June 28, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.