Search code examples
phpapireusabilityslim-3

Unable to call existing internal routes in a Slim API


I am currently developing a RESTful API to maintain a number of databases. Ideally I should be able to call my APIs routes from another route within my application, correct?

I've tried using subRequest in order to call an existing route to no avail. All I get is the following while executing my route in Postman:

<html>
    <head>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
        <title>Slim Application Error</title>
        <style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{display:inline-block;width:65px;}</style>
    </head>
    <body>
        <h1>Slim Application Error</h1>
        <p>A website error has occurred. Sorry for the temporary inconvenience.</p>
    </body>
</html>

Below are my companies.php API routes to get all companies in a table and to put a new company into the companies table.

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

// Get all companies
$app->get('/companies', function(Request $request, Response $response) {
  $sql = "SELECT * FROM companies";

  try {
    // Get DB Object
    $db = new db();
    // Connect
    $db = $db->connect();

    $stmt = $db->query($sql);
    $companies = $stmt->fetchAll(PDO::FETCH_OBJ);
    $db = null;

    echo '{"data":' . json_encode($companies) . '}';
  } catch(PDOException $e) {
    echo '{"error": { "text":' . $e->getMessage() . '}}';
  }
});

// Add new company to companies table
$app->put('/new/company/{companyName}', function(Request $request, Response $response) {
  $newCompany = $request->getAttribute('companyName');

  $insert_sql = "INSERT INTO companies (company_name) VALUE (:newCompany)";

  try {
    $db = new db();
    $db = $db->connect();

    $insert_stmt = $db->prepare($insert_sql);
    $newCompany = str_replace("'", "", $newCompany);
    $insert_stmt->bindParam(':newCompany', $newCompany);
    $insert_stmt->execute();

    $newID = $db->lastInsertId();
    $db = null;

    echo '{"notice": {"text": "New Company Added (cid: '.$newID.')"}';
  } catch(PDOException $e) {
    echo '{"error": { "text":' . $e->getMessage() . '}}';
  }
});

Within a different route, sites.php, I would like to run the PUT->'/new/company' route. So, somewhere within sites.php I place the following:

  $destinationComp = "myNewCompany";
  $res = $this->subRequest('PUT', '/new/company/' . $destinationComp);
  echo $res;

I would expect my output to be the same as if I made a PUT request manually from Postman, instead of the error listed in the first code-section.

Furthermore, I've tried modifying my route call to include use ($app) in hopes of making a regular request through the $app variable rather than $this, is case $this wasn't working. Which looked like:

$app->put('/new/site/{sourceCompany}/{sourceProperty}/{destinationCompany}/{destinationProperty}', function(Request $request, Response $response) use ($app) {
   $destinationComp = "myNewCompany";
   $res = $app->put("/new/company/$destinationComp");
   echo $res;

   //More code to follow...
}

Only to receive the same error message in Postman upon execution.

Any suggestions?


Solution

  • You are attempting to call the subRequest method on the Container class, when it should be the App class.

    inside route closure, $this is bound to the instance of Slim\Container - Slim docs

    Reference the $app var instead, inject it with use keyword. In addition, return the response object instead of doing echo:

    return $app->subRequest('PUT', '/new/company/' . $destinationComp);