Slim4 internal endpoint call

Hi there,

I am kind of new to slim and backend development. I have a simple API in slim4, which just returns json objects to React FE.

Now I have a question if there is a way to call a route from another one. The example:

I have route which returns all permissions which are belongs to specific Role ID in Database.

api/v2/admin/permissions/role/{id}

The code for this part:

$group->get(‘/role/{id}’, \Controller\V2\Admin\PermissionsController::class . ‘:getByRole’);

There is another route which return the information about the specific role

api/v2/role/{id}
$group->get(‘/[{id}]’, \Controller\V2\Admin\RolesController::class . ‘:get’);

And part of this json object which i return is a list of all permissions. Now I use exactly the same DB query in both controllers, but this is like MEH… for example when the DB structure for permssions change I will have to change this query everywhere, so much simplier would be one route (the first one mentioned) and than call that from other controllers.

The simple solution which came up was to use curl, or file_get_content a just access that route → the problem here is that the routes are behind middleware, which is checking JWT auth and that internal calls has no way to get valid auth token.

Is there a way to do that? Like for example not to call the route, but directly that controller method (I have no clue how to do this).

Hope some understand this and thanks for help :slight_smile:

Oh well, I came up with a workaround, but not sure thats the best way.

In Permssion controller i split the function → extract the DB query to separate function like:

public function getByRole(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        try {
            $permissions = $this->selectPermByRole($args['id']);
            $response->getBody()->write(json_encode($permissions));
            return $response;
        } catch (Exception $e) {
            $response->getBody()->write('Something went wrong, try again later');
            return $response->withStatus(400);
        }
    }
    public function selectPermByRole ($id){
        return \DB::query('SELECT permissions.id, permissions.perm, permissions.description, permissions.name FROM permissions JOIN role_has_permissions ON permissions.id = role_has_permissions.permission JOIN roles ON roles.id=role_has_permissions.role WHERE roles.id = %s', $id);
    }

And than I can call selectPermRole from other controller.

Hi! A controller should never call another controller in any way. If you have a shared logic for HTTP specific tasks, you may better implement a middleware. Then add this middleware (e.g. PermissionRoleMiddleware) to the routes and/or route groups you want to protect.