Another approach to design API for improved performance!

Written by gagansandhu | Published 2019/10/02
Tech Story Tags: php | apis | performance | graphql | api | fetch-resources-in-an-api-call | software-development | programming

TLDRvia the TL;DR App

GraphQL is an amazing specification, no doubt about that. I loved it when it first came into my knowledge but as I started learning it, well, I started to hate it and I still do at some extent because I am still learning it. So much boilerplate code to even start the GraphQL server.
Recently, while working on a project, I needed to implement some good amount of API routes and I wasn’t using any specification, neither Rest nor GraphQL. But after working for some days, I faced the usual problem, too many route definitions.
I was thinking of a solution to my problem and I knew GraphQL is there, but I wasn’t feeling like I need that complex API language right now. Anyways, I still tried to implement GraphQL in my project but it was taking too long, maybe because I am new to that.
Instead of spending more time on GraphQL, I made a simple function that replicates the basic functionality of GraphQL engines. Now, I can call multiple operations in the same API call just like GraphQL does but in a few lines of codes. Of course, my little code cannot compete with GraphQL as it is made for large applications and enterprises. Or more specifically, the services that make their APIs public.
I am using Laravel right now but this can be converted to any Framework or just Basic PHP,

1. Define a single point of entry for the API

Route::post('/run', function (Request $request) {
    $response = [];
    $operations = $request->operations;
    if (count($operations) <= 0) {
        return response()->json(["data" => $response]);
    }
    
    foreach ($operations as $operation) {
        $className = $operation['name'];
        $classPath = "App\\Operations\\$className" . "Operation";
        $variables = $operation['variables'] ?? [];
        if (class_exists($classPath)) {
            $response[$className] = (new $classPath())->run($variables); /* run() method will always return an array which is then saved into the $response variable with the OperationName as its key */
        } else {
            $response[$className] = [];
        }
    }
    
    return response()->json(["data" => $response]);
});

2. Creating Operations

The code above simply takes the operations called from API one by one and run the operation files which are defined separately for each operation.
For that, you need to first create a directory to store all the operation, mine is at App\Operations and all the file name inside this directory are suffixed with Operation keyword.

Operation Interface

interface Operation
{
    public function run($variables = []);
}

An example of an operation class

class ExampleOperation
{
    public function run($variables = [])
    {
        // do your stuff here
        // return the response
    }
}

3. Calling Operations from the API

In this case, the VaultBalanceOperation does not exist so it returns an empty array.
This is not a perfect implementation I know. I am not too much into design patterns and fancy stuff. I just had a problem and I tried to solve it. Please don’t compare it with GraphQL, if you want to use GraphQL, go-ahead.
This does not support features like requesting specific fields but I am thinking about it. I have some ideas, will see if that works.
Any doubts or discussions about this, comment below.

Conclusion

Right now, this simple implementation supports multiple resource fetching in a single API call which is very good in terms of performance. You can also pass variables with each operation(for pagination or username/password in login operation). The examples above are using some Laravel stuff as I made this when I working on a project but it can be used in any PHP app or framework easily(Comment if you want to learn how). In the future, I would like to add an option to request only the data we need by mentioning the fields and relationships too.
Follow me to learn more about what I try and do in daily life.



Written by gagansandhu | Full Stack Developer and ML Enthusiast
Published by HackerNoon on 2019/10/02