REST API async?

I am writing a rest api in slim to be used by an app i am also developing. While debugging I noticed that in screens that I do 3-4 Rest calls (3 gets) my calls wait for the previous call to complete before they proceed. I am trying to figure out if this is a problem with my Slim app or my mobile app.

So calling the following endpoints:
domain/rank
domain/leaderboard
domain/activity
domain/user/{id}

They seem to be procedural and not responding as soon as the data is available.

Any help?

ps. I am also attaching an example of an endpoint to make sure that I am not doing something stupid there :slight_smile:

/**
 * Get all Activity Posts
 */
$app->get("/activity", function ($request, $response, $arguments) {
    try
    {
        $stmt = $this->get('pdo')->prepare("SELECT posts.*, users.fname, users.lname, users.privacy, 
                                            users.photo_url as user_avatar 
                                            FROM posts left join users
                                            ON posts.userid = users.id ORDER BY posts.created DESC");
        $stmt->execute();
        $count = $stmt->rowCount();
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        if($count==0)
        {
            $status = 404;
            $responseObject = array();
            $responseObject["status"] = $status;
            $responseObject["error"] = false;
            $responseObject["message"] = "Not found";
        }
        else
        {
            $status = 200;
            $responseObject = array();
            $responseObject["status"] = $status;
            $responseObject["error"] = false;
            $responseObject["data"] = $result;
        }

    }
    catch(\PDOException $e)
    {
        $status = 422;
        $responseObject = array();
        $responseObject["status"] = $status;
        $responseObject["error"] = true;
        $responseObject["message"] = "Server error";
        $responseObject["debug"] = $e->getMessage();
    }

    return $response->withStatus($status)
        ->withHeader('Content-Type', 'application/json')
        ->withJSON($responseObject);

});

Hello!

Maybe are you developing with the PHP Built-in Web Server?

The web server runs only one single-threaded process, so PHP applications will stall if a request is blocked.

https://www.php.net/manual/en/features.commandline.webserver.php

So if for example, you put a sleep(10) in your endpoint of GET ‘domain/rank’ and then make another GET request to ‘domain/leaderboard’, the second request it’s blocked until finish the first request.

It’s just an idea… :slightly_smiling_face: :thinking:

Generally it sounds not good when a web application requires that many requests at the same time.

For simultaneous requests with Axios, you can use Axios.all()

Other ideas:

Most browser limit the number of concurrent network calls. Read more

When your server starts a session it will block all other reqests until its finished. Make sure that you don’t start the session handler. Even if you don’t start it, PHP may start it by default depending on the server configuration.

It looks like this could be the issue. I am testing locally over XAMPP on my windows pc. For my testing i start the server using composer.phar start and test on that.

I guess this uses the build-in web server?

The most requests I have for a single screen are 4 which shouldnt be that many to handle.

Can you elaborate a bit more on what you mean by not starting the session handler?

Thank you.

composer.phar start

I’m not sure, but this looks you are using the internal webserver of PHP and not Apache.
In this case the hint from @maurobonfietti was correct. Please check this first and tell us what web server you are using. Try to start the (XAMPP) Apache webserver instead.

It looks like @maurobonfietti was correct. The issue was using the build in server instead of xampp. All endpoints waited for the previous to complete instead of running at the same time.

Thank you for all the help.

2 Likes

When you execute session_start() with the default session handler, PHP locks the session file to avoid it being written by other processes and releases it on session_write_close() or script completion (whatever comes first). If you’ve added middleware to handle sessions it’s possible that session_start() is running behind the scenes without you even noticing.

The solution is to release the file as soon as you’re done with it ($_SESSION values remain after session_write_close(), you just cannot change them).

That start script should be defined in your application’s composer.json file.