Create a simple REST API with PHP and Slim Framework

0

The trend towards native apps and webapps based mainly on JavaScript has led to more and more REST APIs being developed. For our upcoming project “Herculess”, which is being developed as a native app as well as a JavaScript MVC framework based webapp, we have therefore started to develop such an API.

The key facts for the first version of our API are as follows:

  • PHP-based backend
  • Returns JSON
  • Actions: CRUD: Create, Retrieve, Update, Delete
  • CRUD should use appropriate HTTP headers
  • Authentication will later go over OAuth2, first a simple pseudo implementation for testing

With these data in mind, we started to develop our API.

For this we use the PHP Framework Slim Framework , which is intended exclusively for such REST APIs. After we integrated the framework after the (very simple) tutorial of the website and initialized, here was already laid an essential foundation. The Slim Framework basically takes the routing from us. So we only have to worry about the actual data processing.

For our framework, we use routes that are now used by most APIs. They follow the principle:

/ projects: Returns all projects

/ projects / 1: Returns the project with the ID 1

/ projects / 1 / tasks: Returns all tasks of the project with the ID 1

/ tasks / 1: Returns the task with ID 1

All these routes can basically be used with different HTTP headers (GET for Retrieve, POST for Create, PUT for Update, DELETE for Delete). So, a GET call to / projects will return all projects, while a POST call to / projects will, together with submitted data, create a new project.

We will now briefly explain how we have proceeded so far in the development of this API. We will treat the authentication in a later blog post, in this simple example we assume that everything is publicly accessible.

We have the following folder structure:

  • / Slim (framework files)
  • / classes
    • ApiObject.class.php
    • ApiResultBuilder.class.php
    • Project.class.php
  • index.php
  • .htaccess

In the .htaccess we have the following code, which ensures that we use “nice” URLs like “http://api.com/tasks/1” instead of “http://api.com/index.php/tasks/1” :

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

We will now show, for example, how we implemented the routes / projects and / projects / 1. Other routes are basically handled the same way.
In index.php we integrate the necessary classes and then take care of the routing in a later step:

// Don't forget to load all neccessary classes!
 
// Initialize Slim Framework
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
 
$api = new \Slim\Slim();
 
$api->get('/projects', function ($) {
  // todo
}
 
$api->get('/projects/:uid', function ($uid) {
  // todo
}
 
$api->run();

Here we see how routing works with Slim. The actual data processing happens in the respective classes, in this case in the Project.class.php.
But what are the other three classes we’ve done?

The ApiObject class is the template from which the other Api classes, such as Project or Task, inherit. In the current implementation, there are no specific requirements here, we have implemented this only for future expandability.

The ApiResultBuilder class is responsible for the actual setup of the JSON response. We have implemented this so that there is always a uniform return, and in case of an API change that needs to be changed only in one place.

We want to achieve a return as follows:

{
    "status": {
        "code": 100,
        "message": "OK"
    },
    "projects": [
        {
            //Objekt1
        },
        {
            //Objekt2
        },
        //...
    ]
}

In a separate table in the database, we have stored the possible status codes with matching messages. eg. is 100: OK or 205: ENTRY NOT FOUND.

Let’s take a look at the ApiResultBuilder class first.

It has the following methods: addObject (), setStatus (), setDataType (), getStatusMessage (), and out ().

The setStatus () and setDataType () methods set the attributes “status” and “dataType” in the ApiResultBuilder object to a given value. DataType corresponds in the example above to “project”, ie the model name. So we can theoretically return the JSON response with multiple object types. The method getStatusMessage () returns the corresponding status message for the status (for example, “OK” or “ENTRY NOT FOUND”).

The exciting methods are addObject () and out (): the former takes care of adding data to the output, and the latter takes care of assembling the output. The method addObject () takes a normalized object as a transfer parameter and stores it in the object. The out () method then builds the above JSON response from status, statusMessage, dataType, and the stored objects, and outputs them as text.

The processing of the route / projects can then happen as follows:

// Load all Projects from Project class
$projects = Project::getAll();
$apiBuilder = new ApiResultBuilder();
$dataType = "projects";
 
if(count($projects) < 0) {   // No results   $apiBuilder->setStatus(205);
} else {
  foreach($projects as $project) {
    $apiBuilder->addObject($project);
  }
  $apiBuilder->setStatus(100);
}
 
$apiBuilder->setDataType($dataType);
echo $apiBuilder->out();

Thus, the index.php only cares about the routing, the ApiResultBuilder only about the output and the actual classes take care of the data processing. Of course, this example is quite simplified and needs to be extended with queries and authentication. But it can be magnified excellent and provides a sufficient separation of the various code parts.

Who wonders how to eg. deal with POST requests: This is also easy to do with Slim:

$api->post('/projects', function () { ...}

In this block you can then just work normally with $ _REQUEST to use the transferred data.

In this blog post, we have now given a little insight into our approach to API design. Of course, there are thousands of approaches, formatting, and ways to implement such an API. We are happy about alternative ideas in the comments!

Source: http://mfg.fhstp.ac.at/development/erstellung-eines-einfachen-rest-api-backends-mit-php/

Share This:

Leave A Reply

Powered by FrontNet