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.
In this PHP Restful API Framework tutorial we will use SLIM framework to create our REST API.
Table of Contents
Update
This post covers the tutorial with SLIM2, but now the framework is updated to SLIM3 and we have some changes. For the updated tutorial you can watch this Play List that covers every detail of building API with SLIM.
Don’t get confused with the title, the First 11 video on this list covers SLIM only, then if you want you can learn implementing the APIs in android as well.Â
Prerequisites
To go ahead in this PHP Restful API Framework Tutorial you must have these prerquisites.
- Basic Knowledge of PHP
- Basic Knowledge of MySQL Queries
- PHP Storm IDE (Though you can use any other IDE but I personally love PHP Storm)
- WAMP / XAMPP Server (I will be using wamp server)
- 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.
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).
- Now click on SQL and run the following batch query.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
-- Created by Belal Khan (https://www.simplifiedcoding.net) -- 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.
- 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 |
https://www.simplifiedcoding.net/studentapp/v1/assignments/1 | GET |
The above URL will give all the assignments of the student having id 1.
URL | Method |
https://www.simplifiedcoding.net/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.
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.
1 2 3 4 5 6 7 8 |
<?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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
<?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 create .htaccess file to make our URL well formed. So also create .htaccess and write the following rules.
1 2 3 4 5 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
<?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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
//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Â
1 2 3 4 5 6 |
{ "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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//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Â
1 2 3 4 5 6 7 8 9 |
{ "error":false, "id":2, "name":"Belal Khan", "username":"probelalkhan", "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.
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 🙂