Marmelab Blog

Silex Multifetch: Multiplex Requests To Your PHP API Into A Single HTTP call

Cable

In the wonderful world of API applications, HTTP requests are part of the big picture. But Most of the time, a client application needs to fetch more than one resource in order to build a given page. Think about the Facebook mobile app, for instance: to show you the homepage, it must fetch details about your account, your timeline, your friends, etc. This results in additional latency, since every new request implies HTTP transport. On a 3G network, this can hit the usability pretty hard.

What If We Could Reduce The Number Of HTTP Calls?

One solution is to building ad-hoc API endpoints for each client page. However, this defeats the REST architecture ambition, and reduces reusability of the API.

HTTP/2 and SPDY protocols implement multiplexing in the transport layer. Unfortunately, these protocols are not yet available everywhere - let alone your web server.

Facebook already implements Multiple API Requests using Batch Requests on their Graph API. That's a great approach, easy to implement on the client side, and quite easy to do on the server side, too.

We've already talked about this idea of REST requests multiplexing: marmelab recently published a library called koa-multifetch, which adds this exact ability to Node.js applications. But until today, there was no reusable library allowing multifetch in the PHP world.

Introducing Silex Multifetch

Today, Marmelab is happy to open source the Silex Multifetch provider which allows you to reduce the number of HTTP calls on any Silex project.

It's based on internal APIs of the HttpFragmentServiceProvider for making sub requests, and on the Parallel.php library for parallel fetching.

How Does It Work?

We've deliberately based the usage of the Silex provider on the Facebook BAtch Request API (which was also the basis for the koa-multifetch middleware API).

Just send a list of requests to fetch as a JSON object in the request body:

POST /multi HTTP/1.1
Content-Type: application/json
{
    "product": "/products/1",
    "all_users": "/users"
}

And you will get a response aggregating API responses from the two requested routes (/products/1 and /users):

{
    "product": {
        "code":"200",
        "headers":[
            { "name": "Content-Type", "value": "application/json" }
        ],
        "body": "{ id: 1, name: \"ipad2\", stock: 34 }"
    },
    "all_users": {
        "code":"200",
        "headers":[
            { "name": "Content-Type", "value": "application/json" }
        ],
        "body": "[{ id: 2459, login: \"paul\" }, { id: 7473, login: \"joe\" }]"
    }
}

I Want To Use It, Now!

There are just a few steps before you can start to use it in your Silex project.

First, run the following command to install the Multifetch provider:

composer require marmelab/silex-multifetch "[email protected]"

Then, register HttpFragmentServiceProvider and MultifetchServiceProvider:

$app->register(new Silex\Provider\HttpFragmentServiceProvider());
$app->register(new Marmelab\Multifetch\MultifetchServiceProvider());

That's all :)

The MultifetchServiceProvider allows to customize the name and verb of the multifetch route, whether to fetch requests in parallel on in series, etc. You can read the documentation to learn more about installation and usage.

Happy fetching!