Create a RESTful Web Service API with Slim
Slim is micro framework used to work with REST Web Service. REST stands for Representational State Transfer which uses HTTP requests to GET, POST, PUT and DELETE data. Slim makes easy to manage server side codebase where all the server side data stored at single place and can be used by IOS App, Android App and Website as well.
This article explains you how to create REST API using slim framework. Here, I will create sample API to login in application and perform the operation that need user permissions.
RESTful Web Service API in Slim
Let’s start creating service through Slim. It arranges your code into proper format and reduces code complexity.
We need two folders vendor
, classes
which contains user classes. vendor
folder will generate automatically when you update composer.
1
2
3
4
5
6
|
Index.php
.htaccess
Composer.json
/vendor
/classes
---db.php
|
Install Composer
You need composer in your system in order to install slim framework.
Read More:
Install Slim Framework
Open command prompt or Terminal and target to Project Directory. Now, Install slim by executing below command.
1
|
$ composer require slim/slim "^3.0"
|
Composer will install slim and creates compser.json
file in project root directory.
Create appropriate database tables by executing below queries or download and install database structure file.
Create Database
1
|
CREATE DATABASE `db_slim`;
|
tbl_user
Stores details of users.
1
2
3
4
5
6
7
8
9
10
11
|
CREATE TABLE IF NOT EXISTS ` tbl_user` (
`id` int(11) DEFAULT NULL,
`firstname` varchar(50) DEFAULT NULL,
`lastname` varchar(50) DEFAULT NULL,
`username` varchar(50) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`token` varchar(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tbl_user ` (`id`, `firstname`, `lastname`, `username`, `password`, `token`) VALUES
(1, 'Gopal', 'Joshi', 'gopal', '202cb962ac59075b964b07152d234b70', 'qMLM61omO1FJGvST6vgDBIU9j3co92F1juy7iTT4XppE3PzYxP');
|
Note: The tables are only for sample, you can add new fields as per requirement.
tbl_leaves
Stores employee’s leaves data.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
DROP TABLE IF EXISTS `tbl_leaves`;
CREATE TABLE IF NOT EXISTS `tbl_leaves` (
`id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`leave_date` datetime DEFAULT NULL,
`reason` varchar(50) DEFAULT NULL,
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`updated_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tbl_leaves` (`id`, `user_id`, `leave_date`, `reason`, `created_date`, `updated_date`) VALUES
(1, 1, '2017-03-01 15:54:42', 'Bed Health', '2017-03-01 15:54:52', '2017-03-01 15:54:52'),
(2, 1, '2017-03-04 15:54:42', 'Family Tour', '2017-03-01 15:54:52', '2017-03-01 15:54:52');
|
Require the Composer autoloader into your PHP script, and you are ready to start using Slim. Include db.php
will use for various database operations.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
// index.php
require 'vendor/autoload.php';
use \Psr\Http\Message\RequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require 'db.php';
$dbConfig = array(
'host' => 'localhost',
'dbName' => 'db_slim',
'dbUser' => 'gopal',
'dbPassword' => 'testPwd'
);
|
.htaccess
Copy and past below code in .htaccess
file.
1
2
3
4
|
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
|
db.php
Holds all the database related functions such as Login user, Logout User, Getting list of Leaves and Authorize User.
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
|
<?php
/**
* db.php
*/
class Database{
protected $pdo;
function __construct($dbConfig)
{
$this->pdo = $this->getConnection($dbConfig);
}
private function getConnection($config) {
try {
$pdo = new PDO('mysql:host=' . $config['host'] . ';dbname=' . $config['dbName'] . '', $config['dbUser'], $config['dbPassword']);
return $pdo;
} catch (PDOException $e) {
print "Connection Error!: " . $e->getMessage() . " \n";
die();
}
}
public function login($username, $password){
$response = array();
$encPwd = md5($password); // You can use more secure password encryption method
$sql = "SELECT id, firstname, lastname FROM tbl_user WHERE username = :username AND password = :password";
$res = $this->pdo->prepare($sql);
$res->bindParam(':username', $username);
$res->bindParam(':password', $encPwd);
$res->execute();
$record = $res->fetch(PDO::FETCH_ASSOC);
if (!empty($record)) {
$token = $this->getRandom(50);
$updateSql = "UPDATE tbl_user SET token = :token WHERE id = :id";
$updateRes = $this->pdo->prepare($updateSql);
$updateRes->bindParam(':token', $token);
$updateRes->bindParam(':id', $record['id']);
$updateRes->execute();
$response['status'] = 'success';
$response['token'] = $token;
$response['data'] = array( 'firstname' => $record['firstname'], 'lastname' => $record['lastname']);
}else{
$response['status'] = 'fail';
}
return $response;
}
private function verifyToken($token){
$sql = "SELECT id FROM tbl_user WHERE token = :token";
$res = $this->pdo->prepare($sql);
$res->bindParam(':token', $token);
$res->execute();
$record = $res->fetch(PDO::FETCH_ASSOC);
if (!empty($record)) {
return $record['id'];
}else{
return false;
}
}
public function getLeaves($token){
$key = $this->verifyToken($token);
if (!empty($key)) {
$updateSql = "UPDATE tbl_user SET token = :newToken WHERE token = :token";
$updateRes = $this->pdo->prepare($updateSql);
$updateRes->bindParam(':token', $token);
$updateRes->bindParam(':newToken', "");
$updateRes->bindParam(':id', $record['id']);
$updateRes->execute();
$response['status'] = 'success';
}else{
return array('status' => 'fail', 'message' => 'Invalid Token');
}
}
public function getLeaves($token){
$key = $this->verifyToken($token);
if (!empty($key)) {
$sql = "SELECT id, leave_date, reason, created_date FROM tbl_leaves WHERE user_id = :user_id";
$res = $this->pdo->prepare($sql);
$res->bindParam(':user_id', $key);
$res->execute();
$records = $res->fetchAll(PDO::FETCH_ASSOC);
if (!empty($records)) {
return array('status' => 'success', 'message' => '', 'leaves' => $records);
}else{
return array('status' => 'success', 'message' => '', 'leaves' => array());
}
}else{
return array('status' => 'fail', 'message' => 'Invalid Token');
}
}
private function getRandom($length){
$char = array_merge(range(0,9), range('A', 'Z'), range('a', 'z'));
$code = '';
for($i=0; $i < $length; $i++) {
$code .= $char[mt_rand(0, count($char) - 1)];
}
return $code;
}
}
public function logout($token){
$key = $this->verifyToken($token);
if (!empty($key)) {
$updateSql = "UPDATE tbl_user SET token = null WHERE token = :token";
$updateRes = $this->pdo->prepare($updateSql);
$updateRes->bindParam(':token', $token);
$updateRes->execute();
return array('status' => 'success', 'message' => '');
}else{
return array('status' => 'fail', 'message' => 'Invalid Token');
}
}
}
|
– login($username, $password)
used to check weather user is exists in database table or not.
– verifyToken($token)
validates token generated at the time of login against user’s record stored in database.
– getLeaves($token)
used to fetch user’s leaves.
– logout($token)
used to logout user.
You can use NotORM as well provided by slim. We have create new connection of PDO.
Install chrome extension from chrome store to test API response. I recommend to install Postman REST Client Extension. href=https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop“ target=_blank”>Postman REST Client Extension
Create new Slim App and create route for login URL.
URL: http://localhost:80/slim/login
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
$app = new \Slim\App( array("MODE" => "developement") );
$db = new Database($dbConfig);
$app->post('/login', function (Request $request, Response $response, $args) use ($app, $db) {
$apiResponse = array();
$username = $request->getParam('username');
$password = $request->getParam('password');
if (!empty($username) && !empty($password)) {
$code = 200;
$apiResponse = $db->login($username, $password);
}else{
$code = 401;
$apiResponse['status'] = 'fail';
$apiResponse['message'] = 'Please enter required details';
}
return $response->withJson($apiResponse, $code);
});
$app->run();
}
|
Function will get $username
and $password
from user via $_POST
method and checks user is either exists in database or not. If User is exists in table new token will be generated and returns in JSON
response. Store $token
value in global variable will be used later while getting user leaves.
Response:
Here, will request get list of leaves if user token verified successfully.
URL: http://localhost:80/slim/get/leaves
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$app = new \Slim\App( array("MODE" => "developement") );
$db = new Database($dbConfig);
$app->post('/get/leaves', function (Request $request, Response $response, $args) use ($app, $db) {
$apiResponse = array();
$token = $request->getParam('token');
if (!empty($token)) {
$code = 200;
$apiResponse = $db->getLeaves($token);
}else{
$code = 401;
$apiResponse['status'] = 'fail';
$apiResponse['message'] = 'Invalid Token';
}
return $response->withJson($apiResponse, $code);
});
$app->run();
|
First of all user will be verified based on token you have passed in request. If user found having same token than leave records for that user will be returned in JSON
format.
Response:
Logout the user by removing his current token. If Token is not exists than request will return 401 error code with error message Eg. "Invalid Token"
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$app = new \Slim\App( array("MODE" => "developement") );
$db = new Database($dbConfig);
$app->post('/logout', function (Request $request, Response $response, $args) use ($app, $db) {
$apiResponse = array();
$token = $request->getParam('token');
if (!empty($token)) {
$code = 200;
$apiResponse = $db->logout($token);
}else{
$code = 401;
$apiResponse['status'] = 'fail';
$apiResponse['message'] = 'Invalid Token';
}
return $response->withJson($apiResponse, $code);
});
$app->run();
|
Response:
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
|
<?php
require 'vendor/autoload.php';
use \Psr\Http\Message\RequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require 'db.php';
$dbConfig = array(
'host' => 'localhost',
'dbName' => 'db_slim',
'dbUser' => 'root',
'dbPassword' => '123456'
);
$app = new \Slim\App( array("MODE" => "developement") );
$db = new Database($dbConfig);
$app->post('/login', function (Request $request, Response $response, $args) use ($app, $db) {
$apiResponse = array();
$username = $request->getParam('username');
$password = $request->getParam('password');
if (!empty($username) && !empty($password)) {
$code = 200;
$apiResponse = $db->login($username, $password);
}else{
$code = 401;
$apiResponse['status'] = 'fail';
$apiResponse['message'] = 'Please enter required details';
}
return $response->withJson($apiResponse, $code);
});
$app->post('/logout', function (Request $request, Response $response, $args) use ($app, $db) {
$apiResponse = array();
$token = $request->getParam('token');
if (!empty($token)) {
$code = 200;
$apiResponse = $db->logout($token);
}else{
$code = 401;
$apiResponse['status'] = 'fail';
$apiResponse['message'] = 'Invalid Token';
}
return $response->withJson($apiResponse, $code);
});
$app->post('/get/leaves', function (Request $request, Response $response, $args) use ($app, $db) {
$apiResponse = array();
$token = $request->getParam('token');
if (!empty($token)) {
$code = 200;
$apiResponse = $db->getLeaves($token);
}else{
$code = 401;
$apiResponse['status'] = 'fail';
$apiResponse['message'] = 'Invalid Token';
}
return $response->withJson($apiResponse, $code);
});
$app->run();
?>
|
Here, Single user can logged in from only one device simultaneously. If you has already logged from one device and tries to login from another than he will logout from first device automatically.
Read More:
Create Twitter Bot Using Python and Tweepy
sSwitch – JQuery Plugin For Sliding Toggle Switches
How To Create Simple JQuery plugin
How To Implement Infinite Scroll Using JQuery, Ajax and PHP
Integrate Google Prettify in Html Page
Verify Your Server Meets PayPal Payment Gateway Requirements