The previous Post How to create REST API for Android App using PHP, Slim and MySQL – PART 1/2 , we have learned fundamental concepts about REST API and preparing your development environment ready by installing the required tools needed. I hope everyone got good knowledge about REST and other technical areas. Also I am assuming that you got all the required tools installed.

Today we are going to learn how to setup a PHP project and writing the actual code for REST API. Also we’ll learn writing necessary SQL queries to perform database CRUD operations.

DOWNLOAD CODE

8. PHP Project

PHP Project directory structure

PHP project structure

include – All the helpers classes we build placed here.

libs – All the third party libraries goes here. In our case we place Slim library here.

.htaccess – Rules for url structure and other apache rules.

index.php – Takes care of all the API requests.

let’s start the PHP project

1. Goto the location where XAMPP installed and open htdocs folder. The default installation location of XAMPP would be C:/XAMPP. Below is the final PHP project structure we are going to create in this article.

2. Go into htdocs folder and create a folder named todo_list_manager. This will be the root directory of our project. Inside todo_list_manager create two more folders named libsinclude and v1.

3. Now the paste the Slim library inside libs folder. The download link for Slim is provided in Previous part.

4. Normally Slim framework works when index.php includes in the url which makes url not well-formed. So using the .htacess rules we can get rid of index.php from the url and make some friendly urls. Inside v1 folder create a file named .htaccess and paste the following code. (Note that this file name shouldn’t include any additional extension in the name like .txt)

.htaccess

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]

8.1 Preparing Helper Classes

First we start writing set of helper classes required in this project. These helper classes provides necessary functions required to interact with the database.

5. Inside include folder create file named Config.php with following content. This file contains the entire project configuration like database connection parameters and other variables.

Config.php

<?php
/**
 * Database configuration
 */
    define('DB_USERNAME', 'root');
    define('DB_PASSWORD', '');
    define('DB_HOST', 'localhost');
    define('DB_NAME', 'todo_list_manager');

    define('USER_CREATED_SUCCESSFULLY', 0);
    define('USER_CREATE_FAILED', 1);
    define('USER_ALREADY_EXISTED', 2);
?>

6. Create another class named DbConnect.php This class file mainly takes care of database connection.

DbConnect.php

<?php

/**
 * Handling database connection
 */
class DbConnect {

    private $conn;

    function __construct() {
    }

    /**
     * Establishing database connection
     * @return database connection handler
     */
    function connect() {
        include_once dirname(__FILE__) . '/Config.php';

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

        // Check for database connection error
        if (mysqli_connect_errno()) {
            echo "Failed to connect to MySQL: " . mysqli_connect_error();
        }

        // returing connection resource
        return $this->conn;
    }

}

?>

7. The best way to secure the user passwords is not store them as plain text, instead all the passwords should be encrypted before storing in db. The following class takes care of encrypting the user password. Create another file named PassHash.php and paste the following code.

PassHash.php

<?php

class PassHash {

    // blowfish
    private static $algo = '$2a';
    // cost parameter
    private static $cost = '$10';

    // mainly for internal use
    public static function unique_salt() {
        return substr(sha1(mt_rand()), 0, 22);
    }

    // this will be used to generate a hash
    public static function hash($password) {

        return crypt($password, self::$algo .
                self::$cost .
        '$' . self::unique_salt());
    }

    // this will be used to compare a password against a hash
    public static function check_password($hash, $password) {
        $full_salt = substr($hash, 0, 29);
        $new_hash = crypt($password, $full_salt);
        return ($hash == $new_hash);
    }

}

?>

8. Now create another class named DbHandler.php This class is one of the important files in our project which provides necessary functions to perform CRUD operations on the database. Every function is self explanatory by it’s name and comments, I don’t have to have to explain much about them.

DbHandler.php

<?php

/**
 * Class to handle all db operations
 * This class will have CRUD methods for database tables
 */
class DbHandler {

    private $conn;

    function __construct() {
        require_once dirname(__FILE__) . '/DbConnect.php';
        // opening db connection
        $db = new DbConnect();
        $this->conn = $db->connect();
    }

    /* ------------- `users` table method ------------------ */

    /**
     * Creating new user
     * @param String $name User full name
     * @param String $email User login email id
     * @param String $password User login password
     */
    public function createUser($name, $email, $password) {
        require_once 'PassHash.php';
        $response = array();

        // First check if user already existed in db
        if (!$this->isUserExists($email)) {
            // Generating password hash
            $password_hash = PassHash::hash($password);

            // Generating API key
            $api_key = $this->generateApiKey();

            // insert query
            $stmt = $this->conn->prepare("INSERT INTO users(name, email, password_hash, api_key, status) values(?, ?, ?, ?, 1)");
            $stmt->bind_param("ssss", $name, $email, $password_hash, $api_key);

            $result = $stmt->execute();

            $stmt->close();

            // Check for successful insertion
            if ($result) {
                // User successfully inserted
                return USER_CREATED_SUCCESSFULLY;
            } else {
                // Failed to create user
                return USER_CREATE_FAILED;
            }
        } else {
            // User with same email already existed in the db
            return USER_ALREADY_EXISTED;
        }

        return $response;
    }

    /**
     * Checking user login
     * @param String $email User login email id
     * @param String $password User login password
     * @return boolean User login status success/fail
     */
    public function checkLogin($email, $password) {
        // fetching user by email
        $stmt = $this->conn->prepare("SELECT password_hash FROM users WHERE email = ?");

        $stmt->bind_param("s", $email);

        $stmt->execute();

        $stmt->bind_result($password_hash);

        $stmt->store_result();

        if ($stmt->num_rows > 0) {
            // Found user with the email
            // Now verify the password

            $stmt->fetch();

            $stmt->close();

            if (PassHash::check_password($password_hash, $password)) {
                // User password is correct
                return TRUE;
            } else {
                // user password is incorrect
                return FALSE;
            }
        } else {
            $stmt->close();

            // user not existed with the email
            return FALSE;
        }
    }

    /**
     * Checking for duplicate user by email address
     * @param String $email email to check in db
     * @return boolean
     */
    private function isUserExists($email) {
        $stmt = $this->conn->prepare("SELECT id from users WHERE email = ?");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }

    /**
     * Fetching user by email
     * @param String $email User email id
     */
    public function getUserByEmail($email) {
        $stmt = $this->conn->prepare("SELECT name, email, api_key, status, created_at FROM users WHERE email = ?");
        $stmt->bind_param("s", $email);
        if ($stmt->execute()) {
            // $user = $stmt->get_result()->fetch_assoc();
            $stmt->bind_result($name, $email, $api_key, $status, $created_at);
            $stmt->fetch();
            $user = array();
            $user["name"] = $name;
            $user["email"] = $email;
            $user["api_key"] = $api_key;
            $user["status"] = $status;
            $user["created_at"] = $created_at;
            $stmt->close();
            return $user;
        } else {
            return NULL;
        }
    }

    /**
     * Fetching user api key
     * @param String $user_id user id primary key in user table
     */
    public function getApiKeyById($user_id) {
        $stmt = $this->conn->prepare("SELECT api_key FROM users WHERE id = ?");
        $stmt->bind_param("i", $user_id);
        if ($stmt->execute()) {
            // $api_key = $stmt->get_result()->fetch_assoc();
            // TODO
            $stmt->bind_result($api_key);
            $stmt->close();
            return $api_key;
        } else {
            return NULL;
        }
    }

    /**
     * Fetching user id by api key
     * @param String $api_key user api key
     */
    public function getUserId($api_key) {
        $stmt = $this->conn->prepare("SELECT id FROM users WHERE api_key = ?");
        $stmt->bind_param("s", $api_key);
        if ($stmt->execute()) {
            $stmt->bind_result($user_id);
            $stmt->fetch();
            // TODO
            // $user_id = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            return $user_id;
        } else {
            return NULL;
        }
    }

    /**
     * Validating user api key
     * If the api key is there in db, it is a valid key
     * @param String $api_key user api key
     * @return boolean
     */
    public function isValidApiKey($api_key) {
        $stmt = $this->conn->prepare("SELECT id from users WHERE api_key = ?");
        $stmt->bind_param("s", $api_key);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }

    /**
     * Generating random Unique MD5 String for user Api key
     */
    private function generateApiKey() {
        return md5(uniqid(rand(), true));
    }

    /* ------------- `tasks` table method ------------------ */

    /**
     * Creating new task
     * @param String $user_id user id to whom task belongs to
     * @param String $task task text
     */
    public function createTask($user_id, $task) {
        $stmt = $this->conn->prepare("INSERT INTO tasks(task) VALUES(?)");
        $stmt->bind_param("s", $task);
        $result = $stmt->execute();
        $stmt->close();

        if ($result) {
            // task row created
            // now assign the task to user
            $new_task_id = $this->conn->insert_id;
            $res = $this->createUserTask($user_id, $new_task_id);
            if ($res) {
                // task created successfully
                return $new_task_id;
            } else {
                // task failed to create
                return NULL;
            }
        } else {
            // task failed to create
            return NULL;
        }
    }

    /**
     * Fetching single task
     * @param String $task_id id of the task
     */
    public function getTask($task_id, $user_id) {
        $stmt = $this->conn->prepare("SELECT t.id, t.task, t.status, t.created_at from tasks t, user_tasks ut WHERE t.id = ? AND ut.task_id = t.id AND ut.user_id = ?");
        $stmt->bind_param("ii", $task_id, $user_id);
        if ($stmt->execute()) {
            $res = array();
            $stmt->bind_result($id, $task, $status, $created_at);
            // TODO
            // $task = $stmt->get_result()->fetch_assoc();
            $stmt->fetch();
            $res["id"] = $id;
            $res["task"] = $task;
            $res["status"] = $status;
            $res["created_at"] = $created_at;
            $stmt->close();
            return $res;
        } else {
            return NULL;
        }
    }

    /**
     * Fetching all user tasks
     * @param String $user_id id of the user
     */
    public function getAllUserTasks($user_id) {
        $stmt = $this->conn->prepare("SELECT t.* FROM tasks t, user_tasks ut WHERE t.id = ut.task_id AND ut.user_id = ?");
        $stmt->bind_param("i", $user_id);
        $stmt->execute();
        $tasks = $stmt->get_result();
        $stmt->close();
        return $tasks;
    }

    /**
     * Updating task
     * @param String $task_id id of the task
     * @param String $task task text
     * @param String $status task status
     */
    public function updateTask($user_id, $task_id, $task, $status) {
        $stmt = $this->conn->prepare("UPDATE tasks t, user_tasks ut set t.task = ?, t.status = ? WHERE t.id = ? AND t.id = ut.task_id AND ut.user_id = ?");
        $stmt->bind_param("siii", $task, $status, $task_id, $user_id);
        $stmt->execute();
        $num_affected_rows = $stmt->affected_rows;
        $stmt->close();
        return $num_affected_rows > 0;
    }

    /**
     * Deleting a task
     * @param String $task_id id of the task to delete
     */
    public function deleteTask($user_id, $task_id) {
        $stmt = $this->conn->prepare("DELETE t FROM tasks t, user_tasks ut WHERE t.id = ? AND ut.task_id = t.id AND ut.user_id = ?");
        $stmt->bind_param("ii", $task_id, $user_id);
        $stmt->execute();
        $num_affected_rows = $stmt->affected_rows;
        $stmt->close();
        return $num_affected_rows > 0;
    }

    /* ------------- `user_tasks` table method ------------------ */

    /**
     * Function to assign a task to user
     * @param String $user_id id of the user
     * @param String $task_id id of the task
     */
    public function createUserTask($user_id, $task_id) {
        $stmt = $this->conn->prepare("INSERT INTO user_tasks(user_id, task_id) values(?, ?)");
        $stmt->bind_param("ii", $user_id, $task_id);
        $result = $stmt->execute();

        if (false === $result) {
            die('execute() failed: ' . htmlspecialchars($stmt->error));
        }
        $stmt->close();
        return $result;
    }

}

?>

8.2 Handling the API calls

Now we have all the required classes for the REST API. Now we can start the code to handle all individual API calls.

8. Inside v1 folder create a file named index.php and add the following code. Here we are including required libraries and other helper functions.

verifyRequiredParams() – This function verifies the mandatory parameters in the request.

validateEmail() – Verifies whether email address is valid one or not.

echoRespnse() – This function will echo the JSON response with a status code.

index.php

<?php

        require_once '../include/DbHandler.php';
        require_once '../include/PassHash.php';
        require '.././libs/Slim/Slim.php';

        \Slim\Slim::registerAutoloader();

        $app = new \Slim\Slim();

// User id from db - Global Variable
        $user_id = NULL;

/**
 * Verifying required params posted or not
 */
        function verifyRequiredParams($required_fields) {
        $error = false;
        $error_fields = "";
        $request_params = array();
        $request_params = $_REQUEST;
        // Handling PUT request params
        if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
        $app = \Slim\Slim::getInstance();
        parse_str($app->request()->getBody(), $request_params);
        }
        foreach ($required_fields as $field) {
        if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
        $error = true;
        $error_fields .= $field . ', ';
        }
        }

        if ($error) {
        // Required field(s) are missing or empty
        // echo error json and stop the app
        $response = array();
        $app = \Slim\Slim::getInstance();
        $response["error"] = true;
        $response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
        echoRespnse(400, $response);
        $app->stop();
        }
        }

/**
 * Validating email address
 */
        function validateEmail($email) {
        $app = \Slim\Slim::getInstance();
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $response["error"] = true;
        $response["message"] = 'Email address is not valid';
        echoRespnse(400, $response);
        $app->stop();
        }
        }

/**
 * Echoing json response to client
 * @param String $status_code Http response code
 * @param Int $response Json response
 */
        function echoRespnse($status_code, $response) {
        $app = \Slim\Slim::getInstance();
        // Http response code
        $app->status($status_code);

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

        echo json_encode($response);
        }
     $app->run();
?>

8.3 The JSON response

On calling every API request a JSON response will be issued with a HTTP status code. On the client side you have to verify the response http status code. If the status is 200, the request is processed successfully. Also you can notice a “error” node in the response. If the error value is true, that means some error occurred while processing the user data.

Api Calls without Authentication (without API key in the request header)

These calls don’t have to include Api Key in the request header. The main purpose of these calls is to interact with database without any authentication. User registration and login comes under this category.

8.4 User Registration

In order to interact with the API, the user has to register in our system first. Once he registered an API key will be generated and stored in the database. This API key will be private to that user only.

9. Add the following code in index.php. This function handles user registration.

index.php

/**
 * User Registration
 * url - /register
 * method - POST
 * params - name, email, password
 */
$app->post('/register', function() use ($app) {
        // check for required params
        verifyRequiredParams(array('name', 'email', 'password'));

        $response = array();

        // reading post params
        $name = $app->request->post('name');
        $email = $app->request->post('email');
        $password = $app->request->post('password');

        // validating email address
        validateEmail($email);

        $db = new DbHandler();
        $res = $db->createUser($name, $email, $password);

        if ($res == USER_CREATED_SUCCESSFULLY) {
        $response["error"] = false;
        $response["message"] = "You are successfully registered";
        } else if ($res == USER_CREATE_FAILED) {
        $response["error"] = true;
        $response["message"] = "Oops! An error occurred while registereing";
        } else if ($res == USER_ALREADY_EXISTED) {
        $response["error"] = true;
        $response["message"] = "Sorry, this email already existed";
        }
        // echo json response
        echoRespnse(201, $response);
        });

In the following table you can find the API request information about the URL, HTTP method and the parameters needed to be posted.

URL /register
Method POST
Params name, email, password

Upon the successful registration the following json response will be issued.

{
        "error": false,
        "message": "You are successfully registered"
        }

If the request is missing mandatory parameters the following json will be issued.

{
        "error": true,
        "message": "Required field(s) name, email, password is missing or empty"
        }

8.5 User Login

10. Add the following code to handle user login. After verifying user credentials, the API Key for that user will be issued in the JSON response. The API key should be included in the request header in all remaining API calls.

index.php

/**
 * User Login
 * url - /login
 * method - POST
 * params - email, password
 */
$app->post('/login', function() use ($app) {
        // check for required params
        verifyRequiredParams(array('email', 'password'));

        // reading post params
        $email = $app->request()->post('email');
        $password = $app->request()->post('password');
        $response = array();

        $db = new DbHandler();
        // check for correct email and password
        if ($db->checkLogin($email, $password)) {
        // get the user by email
        $user = $db->getUserByEmail($email);

        if ($user != NULL) {
        $response["error"] = false;
        $response['name'] = $user['name'];
        $response['email'] = $user['email'];
        $response['apiKey'] = $user['api_key'];
        $response['createdAt'] = $user['created_at'];
        } else {
        // unknown error occurred
        $response['error'] = true;
        $response['message'] = "An error occurred. Please try again";
        }
        } else {
        // user credentials are wrong
        $response['error'] = true;
        $response['message'] = 'Login failed. Incorrect credentials';
        }

        echoRespnse(200, $response);
        });
URL /login
Method POST
Params email, password

On successful login the following json will be issued.

{
        "error": false,
        "name": "Yash Pawar",
        "email": "yash@gmail.com",
        "apiKey": "25a1569b38d43e55edb66b130faf949f",
        "createdAt": "2020-05-11 19:12:13"
        }

If the credentials are wrong, you can expect the following JSON.

{
        "error": true,
        "message": "Login failed. Incorrect credentials"
        }

8.6 Verifying API Key

While dealing with task data, we need to identify the user using the API key in the request header by reading Authorization field. Basically we’ll look into database for matched API key and get the appropriate user. If the API key not present in users table, then we’ll stop the execution and echo the error JSON.

11. Add the following method in index.php. The method authenticate() will be executed every time before doing any task related operations on database.

index.php

/**
 * Adding Middle Layer to authenticate every request
 * Checking if the request has valid api key in the 'Authorization' header
 */
function authenticate(\Slim\Route $route) {
    // Getting request headers
    $headers = apache_request_headers();
    $response = array();
    $app = \Slim\Slim::getInstance();

    // Verifying Authorization Header
    if (isset($headers['Authorization'])) {
        $db = new DbHandler();

        // get the api key
        $api_key = $headers['Authorization'];
        // validating api key
        if (!$db->isValidApiKey($api_key)) {
            // api key is not present in users table
            $response["error"] = true;
            $response["message"] = "Access Denied. Invalid Api key";
            echoRespnse(401, $response);
            $app->stop();
        } else {
            global $user_id;
            // get user primary key id
            $user_id = $db->getUserId($api_key);
        }
    } else {
        // api key is missing in header
        $response["error"] = true;
        $response["message"] = "Api key is misssing";
        echoRespnse(400, $response);
        $app->stop();
    }
}

If the API key is missing in the request header, the following JSON will be echoed with 400 status code.

{
        "error": true,
        "message": "Api key is misssing"
        }

If the API key is not valid following JSON will echoed with 401 status code.

{
        "error": true,
        "message": "Access Denied. Invalid Api key"
        }

API Calls with Authentication (Including API key in the request)

Following are the API calls should have an API Key in the request header. These API calls primarily deals the user’s task data like creating, reading, updating and deleting.

8.7 Creating New Task

12. Add the following method to create a new task. Here you can notice that authenticate method is called to verify the API key before inserting a new task.

index.php

/**
 * Creating new task in db
 * method POST
 * params - name
 * url - /tasks/
 */
$app->post('/tasks', 'authenticate', function() use ($app) {
        // check for required params
        verifyRequiredParams(array('task'));

        $response = array();
        $task = $app->request->post('task');

        global $user_id;
        $db = new DbHandler();

        // creating new task
        $task_id = $db->createTask($user_id, $task);

        if ($task_id != NULL) {
        $response["error"] = false;
        $response["message"] = "Task created successfully";
        $response["task_id"] = $task_id;
        echoRespnse(201, $response);
        } else {
        $response["error"] = true;
        $response["message"] = "Failed to create task. Please try again";
        echoRespnse(200, $response);
        }
        });
URL /tasks
Method POST
Params task

On successful creation of new task following json will be issued. If you got this json, you can see new row inserted in tasks and user_tasks tables.

{
        "error": false,
        "message": "Task created successfully",
        "task_id": 1
        }

8.8 Getting All Tasks

13. Following method will list down all user’s tasks. We don’t have to submit any params for this API call.

index.php

/**
 * Listing all tasks of particual user
 * method GET
 * url /tasks          
 */
$app->get('/tasks', 'authenticate', function() {
        global $user_id;
        $response = array();
        $db = new DbHandler();

        // fetching all user tasks
        $result = $db->getAllUserTasks($user_id);

        $response["error"] = false;
        $response["tasks"] = array();

        // looping through result and preparing tasks array
        while ($task = $result->fetch_assoc()) {
        $tmp = array();
        $tmp["id"] = $task["id"];
        $tmp["task"] = $task["task"];
        $tmp["status"] = $task["status"];
        $tmp["createdAt"] = $task["created_at"];
        array_push($response["tasks"], $tmp);
        }

        echoRespnse(200, $response);
        });
URL /tasks
Method GET
Params

Following json will be issued for list of tasks. The “tasks” represents list of tasks as an array. Also if the “status” is 0, that means the task is not done yet.

{
    "error": false,
    "tasks": [
        {
        "id": 1,
        "task": "First Task in ToDo List",
        "status": 0,
        "createdAt": "2020-05-11 19:29:14"
        },
        {
        "id": 2,
        "task": "Second Task in ToDo List",
        "status": 0,
        "createdAt": "2020-05-11 19:33:59"
        }
     ]
}

8.9 Getting Single Task

14. Following method will fetch details of single task. You need to append the task id with a / to URL. For an example if you want details of task 2, the URL will be /tasks/2.

index.php

/**
 * Listing single task of particual user
 * method GET
 * url /tasks/:id
 * Will return 404 if the task doesn't belongs to user
 */
$app->get('/tasks/:id', 'authenticate', function($task_id) {
        global $user_id;
        $response = array();
        $db = new DbHandler();

        // fetch task
        $result = $db->getTask($task_id, $user_id);

        if ($result != NULL) {
        $response["error"] = false;
        $response["id"] = $result["id"];
        $response["task"] = $result["task"];
        $response["status"] = $result["status"];
        $response["createdAt"] = $result["created_at"];
        echoRespnse(200, $response);
        } else {
        $response["error"] = true;
        $response["message"] = "The requested resource doesn't exists";
        echoRespnse(404, $response);
        }
        });
URL /tasks/id (id should be replaced with task id)
Method GET
Params

The details of a single task will be in following JSON format.

{
        "error": false,
        "id": 2,
        "task": "Second Task in ToDo List",
        "status": 0,
        "createdAt": "2020-05-11 19:33:59"
        }

If you pass a task id which is not there in the database, you will get 404 not found error.

8.10 Updating Task

15. Following code will take care of updating a task. The URL for this API call is same as getting the details of single task, only difference is we should use PUT method instead of GET.

index.php

/**
 * Updating existing task
 * method PUT
 * params task, status
 * url - /tasks/:id
 */
$app->put('/tasks/:id', 'authenticate', function($task_id) use($app) {
        // check for required params
        verifyRequiredParams(array('task', 'status'));

        global $user_id;
        $task = $app->request->put('task');
        $status = $app->request->put('status');

        $db = new DbHandler();
        $response = array();

        // updating task
        $result = $db->updateTask($user_id, $task_id, $task, $status);
        if ($result) {
        // task updated successfully
        $response["error"] = false;
        $response["message"] = "Task updated successfully";
        } else {
        // task failed to update
        $response["error"] = true;
        $response["message"] = "Task failed to update. Please try again!";
        }
        echoRespnse(200, $response);
        });
URL /tasks/id (id should be replaced with task id)
Method PUT
Params task, status (0 or 1)

Upon successful updation you will get following JSON.

{
        "error": false,
        "message": "Task updated successfully"
        }

8.11 Deleting Task

16. Again delete task URL is same as update task, but this requires DELETE method.

index.php

/**
 * Deleting task. Users can delete only their tasks
 * method DELETE
 * url /tasks
 */
$app->delete('/tasks/:id', 'authenticate', function($task_id) use($app) {
        global $user_id;

        $db = new DbHandler();
        $response = array();
        $result = $db->deleteTask($user_id, $task_id);
        if ($result) {
        // task deleted successfully
        $response["error"] = false;
        $response["message"] = "Task deleted succesfully";
        } else {
        // task failed to delete
        $response["error"] = true;
        $response["message"] = "Task failed to delete. Please try again!";
        }
        echoRespnse(200, $response);
        });
URL /tasks/id (id should be replaced with task id)
Method DELETE
Params

You will get following json if the task is deleted successfully.

{
        "error": false,
        "message": "Task deleted succesfully"
        }

Here we completes the PHP and MySQL part. Now it’s time to move on to testing the API just to make sure that whatever code we have written is working.

Testing the API

Following is the list of URL we need to test using Chrome Advanced REST client extension with possible combinations of inputs.

URL Method Parameters Description
http://localhost/task_manager/v1/register POST name, email, password User registration
http://localhost/task_manager/v1/login POST email, password User login
http://localhost/task_manager/v1/tasks POST task To create new task
http://localhost/task_manager/v1/tasks GET   Fetching all tasks
http://localhost/task_manager/v1/tasks/:id GET   Fetching single task
http://localhost/task_manager/v1/tasks/:id PUT   Updating single task
http://localhost/task_manager/v1/tasks/:id DELETE task, status Deleting single task

Happy Coding 😀