New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
REST API profiling #252
Comments
|
I'm not sure if you can profile real-time, unless you also send the API requests with the same app. You could use the browse button to view previous requests, which should include the API requests. |
|
That is at least, assuming your app is the one that returns the JSON. Or is your app making the API requests and you want to log Guzzle or something? |
|
@barryvdh I see this kind of issue all over the repo. Would also like to see a way to profile apis built with Laravel. Exactly how Debug Bar works now, just a way to pull the data so it can be attached to a JSON response. |
|
+1.. this would be incredibly useful. |
|
+1 Lots of people would find this helpful |
|
+1 |
|
+1 Do you have any workaround for now ? |
|
Same here. I am googling a built-in way which can send the profiling data to the RESTful API response, and it seems no that way. My current solution is attaching a middleware that adding the profiling data to the response, then enable this middleware for the Api routes group. For example: <?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\JsonResponse;
class ProfileJsonResponse
{
/**
* 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 JsonResponse &&
app()->bound('debugbar') &&
app('debugbar')->isEnabled() &&
is_object($response->getData())
) {
$response->setData($response->getData(true) + [
'_debugbar' => app('debugbar')->getData(),
]);
}
return $response;
}
} |
|
+1 |
|
I have updated the previous example code. |
|
The middleware solution works PERFECTLY. would be nice though if this was integrated in. |
|
Is there a way to generate the debugbar on SPA? @ElfSundae solution returns all the json the data with |
|
I have adjusted @ElfSundae solution to also work when using dingo/api to handle your API responses (using the Dingo response builders): <?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()
) {
$response->setContent(json_decode($response->morph()->getContent(), true) + [
'_debugbar' => app('debugbar')->getData(),
]);
}
return $response;
}
} |
|
@kishanmd Sometimes output of ...
$content = json_decode($response->morph()->getContent(), true) ?? [];
$response->setContent($content + [
'_debugbar' => app('debugbar')->getData(),
]);
... |
|
if you use Postman to test your api, add |
|
Maybe that's unrelated, but I'm developing an API using Laravel and we have another team working on a second Laravel application that happens to consume the API served by the former. When they want to profile their application as well as our underlying API they consume, they simply have both applications storing their JSON dumps in the same folder. Both application have Pretty straight forward from there. The bar in the Web application prompts dumps from both the Web and the API applications. If your environment doesn't define DEBUGBAR_STORAGE_ENABLED and DEBUGBAR_STORAGE_PATH, debugbar simply defaults to the regular storage. |
|
I'm using the middleware solution above. Works perfectly |
|
@yangliuyu indeed, though it'd be nice and easier to let Laravel handle the return: |
|
This seems to work very well with Postman for me. I just turn Debug Bar on, make the API call with Postman, then go to the Folder icon and choose the latest request: http://zsl.io/pwIN9o. You'll need at least one web route so you can view Debug Bar, but no need to refresh that page or anything between requests. Clicking the Folder icon pulls the requests from the storage folder via. ajax. |
|
nice info! thanks @zlanich . |
|
I can't get the debug toolbar to display in Postman app. The json files are written to storage/debugtoolbar but postman I think does not allow javascript in preview. So the question remains - how to profile API requests, when they have header info or post params that needs to be sent, and therefore can't be tested in a normal browser. My workaround is to use the history feature on a normal web page in same project. |
|
@PaddyLock see @blue7wings's answer above. |
|
There's an alternative specifically for monitoring APIs which our company is using now: itsgoingd/clockwork |
|
Yeah and https://github.com/laravel/telescope ofcourse now. |
I tried that but postman does still not show it |
Trying telescope now. Works a treat. Same as debug toolbar history really though for requests, and the way it is used on a separate web page, rather than at the bottom of the response. |
<?php
namespace App\Http\Middleware;
use Closure;
use Dingo\Api\Http\Response;
class ProfileJsonHttpResponse
{
/**
* 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,
]
]);
}
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);
}
}Thanks for @ElfSundae and @kishanmd, I've just put the sql filter to get only sql and each duration. Thanks @barryvdh for this awesome package. |
Whereas Telescope is a useful tool, it does not provide performance information. |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
|
+1 |
|
+1 |
|
+1 for SPA |
|
I just have updated middleware for php 8 <?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
class ProfileJsonHttpResponse
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
$response = $next($request);
if (
$response instanceof JsonResponse &&
app()->bound('debugbar') &&
app('debugbar')->isEnabled() &&
env('API_DEBUG', false)
) {
$queriesData = $this->sqlFilter(app('debugbar')->getData());
$responseData = json_decode($response->getContent(), true) + [
'_debugbar' => [
'total_queries' => count($queriesData),
'duplicates' => collect($queriesData)
->groupBy('sql')
->map(fn ($rows) => $rows->count())
->map(fn ($value, $index) => [
'sql' => $index,
'total' => $value
])
->sortByDesc('total')
->values()
->toArray(),
'queries' => $queriesData,
]
];
$response = $response->setContent(json_encode($responseData));
}
return $response;
}
/**
* Get sql queries information.
*
* @param array $debugbarData
* @return array
*/
protected function sqlFilter(array $debugbarData): array
{
$result = Arr::get($debugbarData, 'queries.statements');
return array_map(fn ($item) => [
'sql' => Arr::get($item, 'sql'),
'duration' => Arr::get($item, 'duration_str'),
'stmt_id' => Arr::get($item, 'stmt_id'),
'backtrace' => collect(Arr::get($item, 'backtrace'))->mapWithKeys(fn ($item) => [
$item->index => "{$item->name}:{$item->line}"
]),
], $result);
}
} |


Hi! I'm having an API built with laravel. And I need to do some profiling on it.
It's the classic REST API that returns json.
How can I profile it with debugbar?
The text was updated successfully, but these errors were encountered: