Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

API Debugging with the Profiler

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Debugging an API... can be tough... because you don't see the results - or errors - as big HTML pages. So, to help us along the way, let's level-up our debugging ability! In a traditional Symfony app, one of the best features is the web debug toolbar... which we don't see down here right now because it's not installed yet.

Using the Profiler in an API

But... should we even bother? I mean, it's not like we can see the web debug toolbar on a JSON API response, right? Of course we can! Well, sort of.

Find your terminal and get the profiler installed with:

composer require profiler --dev

You can also run composer require debug --dev to install a few extra tools. This installs the WebProfilerBundle, which adds a couple of configuration files to help it do its magic.

Thanks to these, when we refresh... there it is! The web debug toolbar floating on the bottom. This is literally the web debug toolbar for this documentation page... which probably isn't that interesting.

But if we start making requests... check it out. When we execute an operation via Swagger, it makes an AJAX request to complete the operation. And Symfony's web debug toolbar has a cool little feature where it tracks those AJAX requests and adds them to a list! Every time I hit execute, I get a new one!

The real magic is that you can click the little "sha" link to see the profiler for that API request! So... yea! You can't see the web debug toolbar for a response that returns JSON, but you can still see the profiler, which contains way more data anyways, like the POST parameters, the request headers, request content - which is really important when you're sending JSON - and all the goodies that you expect - cache, performance, security, Doctrine, etc.

Finding the Profile for an API Request

In addition to the little web debug toolbar AJAX tracker we just saw, there are a few other ways to find the profiler for a specific API request. First, every response has an x-debug-token-link header with a URL to its profiler page, which you can read to figure out where to go. Or, you can just go to /_profiler to see a list of the most recent request. Here's the one for /api/cheese_listings. Click the token to jump into its profiler.

The API Platform Panel

Oh, and API Platform adds its own profiler panel, which is a nice way to see which resource this request was operating on and the metadata for it, including this item operation and collection operation stuff - we'll talk about those really soon. It also shows info about "data providers" and "data persisters" - two important concepts we'll talk about later.

But before we get there, back on the documentation page, we need to talk about these five endpoints - called operations - and how we can customize them.

Leave a comment!

2
Login or Register to join the conversation

Hi, any idea as to why a request to fetch an id takes around 2.4 seconds? Quite slow. Is it because I'm running Windows 10 or did I miss something? My other pure web SF4 projects run a request in less than 500ms on the same platform

Reply

Hey jpfortuno

Are you on Windows WSL? Because it has a very poor performance with files operations.
Another thing to consider is the first time you execute a request Symfony has to bootstrap the entire app but it creates a cache, so, if you don't modify any file after that, the subsequent requests ought to be faster

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial works great for Symfony 5 and API Platform 2.5/2.6.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.1.3",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "api-platform/core": "^2.1", // v2.4.3
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "doctrine/annotations": "^1.0", // 1.10.2
        "doctrine/doctrine-bundle": "^1.6", // 1.11.2
        "doctrine/doctrine-migrations-bundle": "^2.0", // v2.0.0
        "doctrine/orm": "^2.4.5", // v2.7.2
        "nelmio/cors-bundle": "^1.5", // 1.5.5
        "nesbot/carbon": "^2.17", // 2.19.2
        "phpdocumentor/reflection-docblock": "^3.0 || ^4.0", // 4.3.1
        "symfony/asset": "4.2.*|4.3.*|4.4.*", // v4.3.11
        "symfony/console": "4.2.*", // v4.2.12
        "symfony/dotenv": "4.2.*", // v4.2.12
        "symfony/expression-language": "4.2.*|4.3.*|4.4.*", // v4.3.11
        "symfony/flex": "^1.1", // v1.17.6
        "symfony/framework-bundle": "4.2.*", // v4.2.12
        "symfony/security-bundle": "4.2.*|4.3.*", // v4.3.3
        "symfony/twig-bundle": "4.2.*|4.3.*", // v4.2.12
        "symfony/validator": "4.2.*|4.3.*", // v4.3.11
        "symfony/yaml": "4.2.*" // v4.2.12
    },
    "require-dev": {
        "symfony/maker-bundle": "^1.11", // v1.11.6
        "symfony/stopwatch": "4.2.*|4.3.*", // v4.2.9
        "symfony/web-profiler-bundle": "4.2.*|4.3.*" // v4.2.9
    }
}
userVoice