PHP Restful API Framework SLIM to Create REST API - 1

  • Posted by:

    Kashfur Rehmaan
  • Posted on:

    Feb 12, 2017
  • Comments:

    127
  • Total View:

    4289

In this PHP Restful API Framework tutorial we will use SLIM framework to create our REST API.

Hello friends, today we will see how we can use PHP Restful API Framework SLIM to create a REST API for your android application. A REST API is needed to establish the communication between the app and the server. If we talk about android then we cannot use SQLite only to create our database. We need to create the database in our server. So the communication between our database which is residing in server and our app will be done through REST API.

Contents

Requirements

To go ahead in this PHP Restful API Framework Tutorial you must have these prerquisites.

  1. Basic Knowledge of PHP
  2. Basic Knowledge of MySQL Queries
  3. PHP Storm IDE (Though you can use any other IDE but I personally love PHP Storm)
  4. WAMP / XAMPP Server (I will be using wamp server)
  5. REST Client for Firefox or Chrome for Testing.

What is REST API?

When a web service use REST Architecture we call it a REST API. REST stands for Representational State Transfer. It relies on a stateless, client-server, cacheable communications protocol, and in virtually all cases, the HTTP protocol is used. REST is an architecture style for designing networked applications.

PHP Restful API Framework SLIM

In this tutorial I will be using SLIM Framework. There are more frameworks available. But I am very comfortable using it. SLIM framework is easy to use and learn. It is also very light weight and supports all kind of requests. So the first thing you need to do is Download SLIM Framework from Here .

What I will be creating in this PHP Restful API Framework Tutorial?

In this tutorial I will create a simple Android App. The app will contain two modules.

1. Student’s Module

The student will login to the app and he/she can see whether his/her assignment is submitted successfully or not. Student can see how many assignment he/she has done so far and what assignment is to be done.

2. Teacher’s Module

Teacher will login to the app and will set an assignment for a particular student. Teacher can change the assignment status to completed if the assignment is completed.

Database Design

For this app the first thing we need is our database. So below you can see the database I have designed.

Database Design
"Database Design"

You can see our database consist of 3 tables. This is only an abstract model now we need to create the actual database.

Creating Database
  • Go to localhost/phpmyadmin (I am using wamp server, make sure your server is online).
  • Create a new database here (I created db_studentapp).

Create database

  • Now click on SQL and run the following batch query.
-- Created by Kashfur Rehmaan (http://kashfur7.ga)

-- tables
-- Table assignments
CREATE TABLE assignments (
    id int  NOT NULL  AUTO_INCREMENT,
    name varchar(100)  NOT NULL,
    details varchar(1000)  NOT NULL,
    completed bool  NOT NULL  DEFAULT false,
    faculties_id int  NOT NULL,
    students_id int  NOT NULL,
    CONSTRAINT assignments_pk PRIMARY KEY (id)
);

-- Table faculties
CREATE TABLE faculties (
    id int  NOT NULL  AUTO_INCREMENT,
    name varchar(100)  NOT NULL,
    username varchar(100)  NOT NULL,
    password varchar(100)  NOT NULL,
    subject varchar(100)  NOT NULL,
    api_key varchar(100)  NOT NULL,
    CONSTRAINT faculties_pk PRIMARY KEY (id)
);

-- Table students
CREATE TABLE students (
    id int  NOT NULL  AUTO_INCREMENT,
    name varchar(100)  NOT NULL,
    username varchar(100)  NOT NULL,
    password varchar(100)  NOT NULL,
    api_key varchar(100)  NOT NULL,
    CONSTRAINT students_pk PRIMARY KEY (id)
);


-- foreign keys
-- Reference:  assignments_faculties (table: assignments)

ALTER TABLE assignments ADD CONSTRAINT assignments_faculties FOREIGN KEY assignments_faculties (faculties_id)
    REFERENCES faculties (id);
-- Reference:  assignments_students (table: assignments)

ALTER TABLE assignments ADD CONSTRAINT assignments_students FOREIGN KEY assignments_students (students_id)
    REFERENCES students (id);



-- End of file.
                
  • After running the above query you will see your tables are created successfully.

Database

  • We have successfully created the database. Keep reading to create the REST API.
Basics of REST API Design

As we have designed our database now we have to create our REST API. Before starting our REST API PHP Project we should know the basics of REST API.

  • HTTP Methods

  • A REST API should use the common HTTP methods like GET, POST, PUT, DELETE. These method are used according to the requirement.

    GET To Retrieve Values from Database
    POST To Insert new Values to Database
    PUT To Update Existing Values in the Database
    DELETE To Delete Values from Database

  • HTTP Status Codes

  • Http Status Codes tells the client about the response. Like if the code is 200 that means the response is ok. The code is 401 then it is an unauthorized request. Below I have mentioned some the the request codes for a full list of http request codes you can visit this link .

    200 OK
    201 Created
    304 Not Modified
    400 Bad Request
    401 Unauthorized
    403 Forbidden
    404 Not Found
    422 Unprocessable Entity
    500 Internal Server Error

  • URL Structure

  • While creating REST API we should create good URLs. The URLs should be understandable and well formed. Every URL must be identified uniquely. For security we use API Key with the request. We should not put the API Key in the URL instead we should put the API Key in the request header. For example you can see the following URLs.

    URL Method
    kashfur7.ga/studentapp/v1/assignments/1 GET

    The above URL will give all the assignments of the student having id 1.

    URL Method
    kashfur7.ga/studentapp/v1/createassignment POST

    The above URL will create a new assignment.

  • API Key

  • We use an API Key to restrict the access to our API. In this tutorial we will identify each faculty and student with their API Key. As this post is for beginners I am trying to simplify it as much as I can.

Creating Our REST API
    Creating PHP Project using PHP Storm
    • I am using PHP Storm as I love this IDE. You can use other IDEs as well. You can also use a normal text editor.
    • First you need to create a PHP Project. I am using wamp server so in my case I should create my project at C:\wamp\www\<Project_folder>.
    • I just created a project at C:\wamp\www\StudentApp. You have to create it in the root directory of your server like it will be htdocs folder in case of xampp and www in case of wamp.
    Creating Directories
    • Inside the project you need to create three more folders/directories 1. include, 2. libs, 3. v1.
      In include folder we will keep all the helper classes, in libs folder we will keep all the 3rd party libararies and in v1 folder we will store index.php that will handle all API calls.
      See the snapshot below.

    Directory Structure

    Directory Structure

Coding Helper Classes
  • Now the first is include. You need to create 3 php files inside include folder. Create Constants.php first and write the following code.
<?php
//Constants to connect with the database
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_HOST', 'localhost');
define('DB_NAME', 'db_studentapp');
                
  • Now create DbConnect.php inside include folder. This file will help us to connect with our database. Write the following code inside this file.
<?php

//Class DbConnect
class DbConnect
{
    //Variable to store database link
    private $con;

    //Class constructor
    function __construct()
    {

    }

    //This method will connect to the database
    function connect()
    {
        //Including the constants.php file to get the database constants
        include_once dirname(__FILE__) . '/Constants.php';

        //connecting to mysql database
        $this->con = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);

        //Checking if any error occured while connecting
        if (mysqli_connect_errno()) {
            echo "Failed to connect to MySQL: " . mysqli_connect_error();
        }

        //finally returning the connection link 
        return $this->con;
    }

}
                
  • Now the last file of include folder DbOperation.php, in this file we will write code for all the database related operations. So create DbOperation.php and write the following code.
<?php

class DbOperation
{
    //Database connection link
    private $con;

    //Class constructor
    function __construct()
    {
        //Getting the DbConnect.php file
        require_once dirname(__FILE__) . '/DbConnect.php';

        //Creating a DbConnect object to connect to the database
        $db = new DbConnect();

        //Initializing our connection link of this class
        //by calling the method connect of DbConnect class
        $this->con = $db->connect();
    }

    //Method will create a new student
    public function createStudent($name,$username,$pass){

        //First we will check whether the student is already registered or not
        if (!$this->isStudentExists($username)) {
            //Encrypting the password
            $password = md5($pass);

            //Generating an API Key
            $apikey = $this->generateApiKey();

            //Crating an statement
            $stmt = $this->con->prepare("INSERT INTO students(name, username, password, api_key) values(?, ?, ?, ?)");

            //Binding the parameters
            $stmt->bind_param("ssss", $name, $username, $password, $apikey);

            //Executing the statment
            $result = $stmt->execute();

            //Closing the statment
            $stmt->close();

            //If statment executed successfully
            if ($result) {
                //Returning 0 means student created successfully
                return 0;
            } else {
                //Returning 1 means failed to create student
                return 1;
            }
        } else {
            //returning 2 means user already exist in the database
            return 2;
        }
    }

    //Method for student login
    public function studentLogin($username,$pass){
        //Generating password hash
        $password = md5($pass);
        //Creating query
        $stmt = $this->con->prepare("SELECT * FROM students WHERE username=? and password=?");
        //binding the parameters
        $stmt->bind_param("ss",$username,$password);
        //executing the query
        $stmt->execute();
        //Storing result
        $stmt->store_result();
        //Getting the result
        $num_rows = $stmt->num_rows;
        //closing the statment
        $stmt->close();
        //If the result value is greater than 0 means user found in the database with given username and password
        //So returning true
        return $num_rows>0;
    }

    //This method will return student detail
    public function getStudent($username){
        $stmt = $this->con->prepare("SELECT * FROM students WHERE username=?");
        $stmt->bind_param("s",$username);
        $stmt->execute();
        //Getting the student result array
        $student = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        //returning the student
        return $student;
    }

    //Checking whether a student already exist
    private function isStudentExists($username) {
        $stmt = $this->con->prepare("SELECT id from students WHERE username = ?");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }

    //Method to get assignments
    private function getAssignments($id){
        $stmt = $this->con->prepare("SELECT * FFROM assignments WHERE students_id=?");
        $stmt->bind_param("i",$id);
        $stmt->execute();
        $assignments = $stmt->get_result()->fetch_assoc();
        return $assignments;
    }

    //
    //  Methods to check a user is valid or not using api key
    //  I will not write comments to every method as the same thing is done in each method
    //
    public function isValidStudent($api_key) {
        //Creating an statement
        $stmt = $this->con->prepare("SELECT id from students WHERE api_key = ?");

        //Binding parameters to statement with this
        //the question mark of queries will be replaced with the actual values
        $stmt->bind_param("s", $api_key);

        //Executing the statement
        $stmt->execute();

        //Storing the results
        $stmt->store_result();

        //Getting the rows from the database
        //As API Key is always unique so we will get either a row or no row
        $num_rows = $stmt->num_rows;

        //Closing the statment
        $stmt->close();

        //If the fetched row is greater than 0 returning  true means user is valid
        return $num_rows > 0;
    }

    //This method will generate a unique api key
    private function generateApiKey(){
        return md5(uniqid(rand(), true));
    }
}
                
  • In the above code I have specified methods only for student registration and student login. We have to create all the methods required here like the methods are missing for faculty registration and login. We also need to create the methods to fetch the assignment and update the assignment status. I have not written all the methods here as this tutorial is a bit lengthy I have divided it into two parts. You can find the remaining code in the second part of this PHP REST API Framework SLIM Tutorial .
  • Our helper classes are ready, now we need to handle our API calls.
Handling API Calls
  • Now come inside v1 folder and create file index.php. Here we also need to cr eate .htaccess file to make our URL well formed. So also create .htaccess and write the following rules.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]
  • Now come inside index.php here we will handle all the individual API calls. Here actuallly our php restful api framework slim will be used.
  • So first create a slim instance and some required methods.
<?php

//including the required files
require_once '../include/DbOperation.php';
require '.././libs/Slim/Slim.php';


\Slim\Slim::registerAutoloader();

//Creating a slim instance
$app = new \Slim\Slim();

//Method to display response
function echoResponse($status_code, $response)
{
    //Getting app instance
    $app = \Slim\Slim::getInstance();

    //Setting Http response code
    $app->status($status_code);

    //setting response content type to json
    $app->contentType('application/json');

    //displaying the response in json format
    echo json_encode($response);
}


function verifyRequiredParams($required_fields)
{
    //Assuming there is no error
    $error = false;

    //Error fields are blank
    $error_fields = "";

    //Getting the request parameters
    $request_params = $_REQUEST;

    //Handling PUT request params
    if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
        //Getting the app instance
        $app = \Slim\Slim::getInstance();

        //Getting put parameters in request params variable
        parse_str($app->request()->getBody(), $request_params);
    }

    //Looping through all the parameters
    foreach ($required_fields as $field) {

        //if any requred parameter is missing
        if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
            //error is true
            $error = true;

            //Concatnating the missing parameters in error fields
            $error_fields .= $field . ', ';
        }
    }

    //if there is a parameter missing then error is true
    if ($error) {
        //Creating response array
        $response = array();

        //Getting app instance
        $app = \Slim\Slim::getInstance();

        //Adding values to response array
        $response["error"] = true;
        $response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';

        //Displaying response with error code 400
        echoResponse(400, $response);

        //Stopping the app
        $app->stop();
    }
}

//Method to authenticate a student 
function authenticateStudent(\Slim\Route $route)
{
    //Getting request headers
    $headers = apache_request_headers();
    $response = array();
    $app = \Slim\Slim::getInstance();

    //Verifying the headers
    if (isset($headers['Authorization'])) {

        //Creating a DatabaseOperation boject
        $db = new DbOperation();

        //Getting api key from header
        $api_key = $headers['Authorization'];

        //Validating apikey from database
        if (!$db->isValidStudent($api_key)) {
            $response["error"] = true;
            $response["message"] = "Access Denied. Invalid Api key";
            echoResponse(401, $response);
            $app->stop();
        }
    } else {
        // api key is missing in header
        $response["error"] = true;
        $response["message"] = "Api key is misssing";
        echoResponse(400, $response);
        $app->stop();
    }
}
$app->run();
                
  • The above code consist of the following methods.
    echoResponse() – To display the response in json format.
    authenticateStudent() – To authenticate the student with the api key.
    verifyRequiredParams() – To verify the required parameters in the request.
Student Registration
  • The first task for us is the student registration. So we will create a unique URL for student registration. To do this you need to write the following code inside index.php.
//this method will create a student
//the first parameter is the URL address that will be added at last to the root url
//The method is post
$app->post('/createstudent', function () use ($app) {

    //Verifying the required parameters
    verifyRequiredParams(array('name', 'username', 'password'));

    //Creating a response array
    $response = array();

    //reading post parameters
    $name = $app->request->post('name');
    $username = $app->request->post('username');
    $password = $app->request->post('password');

    //Creating a DbOperation object
    $db = new DbOperation();

    //Calling the method createStudent to add student to the database
    $res = $db->createStudent($name,$username,$password);

    //If the result returned is 0 means success
    if ($res == 0) {
        //Making the response error false
        $response["error"] = false;
        //Adding a success message
        $response["message"] = "You are successfully registered";
        //Displaying response
        echoResponse(201, $response);

    //If the result returned is 1 means failure
    } else if ($res == 1) {
        $response["error"] = true;
        $response["message"] = "Oops! An error occurred while registereing";
        echoResponse(200, $response);

    //If the result returned is 2 means user already exist
    } else if ($res == 2) {
        $response["error"] = true;
        $response["message"] = "Sorry, this email already existed";
        echoResponse(200, $response);
    }
});
            

Now we have the following method for student registration in our API.

URL http://localhost/StudentApp/v1/createstudent
Method POST
Parameters name, username, password

The JSON Response

{
   "error":false,
   "message":"You are successfully registered"
}
Student Login
  • After registration the login part comes. So to create login we will again use post method.
//Login request
$app->post('/studentlogin',function() use ($app){
    //verifying required parameters
    verifyRequiredParams(array('username','password'));

    //getting post values
    $username = $app->request->post('username');
    $password = $app->request->post('password');

    //Creating DbOperation object
    $db = new DbOperation();

    //Creating a response array
    $response = array();

    //If username password is correct
    if($db->studentLogin($username,$password)){

        //Getting user detail
        $student = $db->getStudent($username);

        //Generating response
        $response['error'] = false;
        $response['id'] = $student['id'];
        $response['name'] = $student['name'];
        $response['username'] = $student['username'];
        $response['apikey'] = $student['api_key'];

    }else{
        //Generating response
        $response['error'] = true;
        $response['message'] = "Invalid username or password";
    }

    //Displaying the response
    echoResponse(200,$response);
});

Now we have the following method for student registration in our API.

URL http://localhost/StudentApp/v1/studentlogin
Method POST
Parameters username, password

The JSON Response

{
   "error":false,
   "id":2,
   "name":"Kashfur Rehmaan",
   "username":"prokashfur",
   "apikey":"589d3d5ad22808e7cb54fd1ee2affd3c"
}
Testing Our API
  • To test the API you need a rest client. I am using Rest Easy add on for mozilla firefox. There are many other add ons available you can use any one of them.
  • To test just make a call to the URL using rest client.

Rest easy

Conclusion

So I am wrapping up this tutorial here. As this PHP Restful API Framework Tutorial is a bit lengthy. We still need to create many other things in order to make the android application as per the requirement we discussed. So go to the below link to check the next part of this tutorial

PHP Rest API Framework SLIM to Create REST API – 2

And then after this part of tutorial we will create an Android Application with our RESTful API. If you want to download the source code go to part 2 and you can download the whole source code.

And support us by sharing this PHP Restful API Framework Tutorial among your friends. Thank You 🙂

Related

Related Topics

Post A Reply