0

I am creating an API. In this API I am accessing a (permissions) table from a database multiple times, in middleware as well as in controllers. I was thinking, instead of accessing the database multiple times, why don't I call it once and use it multiple times. After calling it once, I could store it in the cache within a service provider. But I am not sure if it is a good way to go because API routes don't load all the services like session.

There are other ways like storing data into the config. Or create a class and make a facade for it and then call it when ever it is needed. But I am curious if the cache would work in API routes and would it be a good idea?

Snostorp
  • 544
  • 1
  • 8
  • 14
Skeletor
  • 3,201
  • 4
  • 30
  • 51
  • 1
    the type of route doesn't matter, they just have different middleware stacks... if you are hitting something many times for the same data and it isn't changing often then cache could be a good option, but you should test to make sure you are actually getting the benefit from using it ... you also have different ways of looking at caching here, you could just have a runtime cache where an object is just holding these permissions after the first time you retrieve them or you could have them in an actual cache store you directly access – lagbox Jun 14 '20 at 15:49
  • @lagbox hey actually runtime cache would be a great solution because I don't need the data after runtime. And I guess I wouldn't need to clear it afterwards. How could I use that runtime caching? – Skeletor Jun 14 '20 at 15:55
  • 1
    in short you could make something that retrieves all the permission for you (or if it has already retrieved them, just return what it has cached) and bind that to the container and make calls to it when you want to retrieve the permissions, now that one single thing can just store them in an array and it wont continue to hit the database every time ... super simple overview of one concept .. how ever you want to achieve something like that – lagbox Jun 14 '20 at 16:14
  • definitely going to do that. Thank you @lagbox. – Skeletor Jun 14 '20 at 16:43

1 Answers1

0

Okay with the advice of @lagbox I created a dead simple class.

namespace App\Helpers;

use App\Permission;

class Provide
{
    public $permissions = [];

    function __construct() {
        $this->permissions = Permission::whereNotNull('route_name')->get();
    }
}

This may vary, it's just a class that will keep some collection data in it. I named it provide to keep it generic, just in case that I could need other data than permission in the future. Of course this class could be more detailed but just for storing and returning permissions it is enough.

Then I bound it as a singleton in my AppServiceProvider to run it only once.

public function register()
{
    $this->app->singleton('App\Helpers\Provide', function ($app) {
        return new \App\Helpers\Provide();
    });
}

and when I need it I call it like

$provide->permissions->toArray() 

All the features of the collection are available everywhere from the beginning to the end. Yes that may look like an overkill or an abuse of IoC but this über simple approach is in my case a superb solution.

Skeletor
  • 3,201
  • 4
  • 30
  • 51