در قسمت های قبل با اصول کار RESTful API آشنا شدید و پیاده سازی ساده ای از RESTful API را دیدید . در این جلسه قصد داریم تا برنامه API بنویسیم که با بانک اطلاعاتی در ارتباط باشد و بتواند رکوردها را از بانک اطلاعاتی بخواند و برای مشتریان بفرستد.
بانک اطلاعاتی amoozesh را استفاده می کنیم که دارای یک جدول بنام studs برای نگهداری مشخصات دانشجویان است برای ساخت این جدول و اضافه کردن رکوردهای فرضی دستورات SQL زیر را اجرا کنید:
CREATE `studs` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8_persian_ci DEFAULT NULL,
`avgr` float DEFAULT NULL,
`fid` int(11) DEFAULT NULL,
PRIMARY KEY (`sid`)
) ;
INSERT INTO `studs` (`sid`, `name`, `avgr`, `fid`) VALUES
(100, 'ali reza', 18.75, 1),
(103, 'amin', 16.5, 2),
(104, 'sara', 18.25, 2),
(105, 'mina', 18, 2),
(106, 'hadi', 16, 3),
(107, 'mohammad', 19, 2);
ساخت برنامه REST API در بخش سرور
ابتدا در بخش سرور برنامه API را بصورت زیر می نویسیم این فایل را api.php نامگذاری کرده ایم، در این فایل دو متد برای خواندن رکوردها از بانک اطلاعاتی و تولید لیست رکوردها پیاده سازی شده است. یک تابع هم برای ایجاد خروجی به سمت کلاینت نوشته شده است.
فایل api.php را در پوشه server بصورت زیر ذخیره می کنیم:
http://127.0.0.1/restapi/server/api.php
محتوای برنامه REST API (فایل api.php):
<?php
function response($status , $data=0 , $message="OK")
{
header("Content Type :application/json");
header("HTTP/1.1 $status");
$res['status'] = ($status==200)?1:0;
$res['data'] = $data;
$res['message']=$message;
$res=json_encode($res);
echo $res;
exit;
}
function Studs()
{
$conn = mysqli_connect("localhost","root","","amoozesh");
$res= mysqli_query($conn , "SELECT * FROM studs");
$list=[];
while($row=mysqli_fetch_assoc($res))
$list[]=$row;
return $list;
}
function StudsByFid($fid)
{
$conn = mysqli_connect("localhost","root","","amoozesh");
$res= mysqli_query($conn , "SELECT * FROM studs WHERE fid=$fid");
$list=[];
while($row=mysqli_fetch_assoc($res))
$list[]=$row;
return $list;
}
$query = file_get_contents("php://input");
parse_str($query , $params);
if( isset($params['method']) )
{
$method = strtolower($params['method']);
switch($method)
{
case "studs" : $m=Studs();
response(200 , $m);
break;
case "studsbyfid":$m=StudsByFid($params['fid']);
response(200 , $m);
break;
default: response(400 , 0 , "method not defined");
}
} else response(400 , 0 , "method not defined");
?>
در برنامه API از تابع response برای ایجاد پاسخ و ارسال آن استفاده شده است.
function response($status , $data=0 , $message="OK")
{
header("Content Type :application/json");
header("HTTP/1.1 $status");
$res['status'] = ($status==200)?1:0;
$res['data'] = $data;
$res['message']=$message;
$res=json_encode($res);
echo $res;
exit;
}
در این تابع ابتدا نوع خروجی با دستور زیر تنظیم شده:
header("Content Type :application/json");
سپس نسخه HTTP و کد وضعیت تعیین شده :
header("HTTP/1.1 $status");
در ادامه یک آرایه انجمنی بنام res با سه کلید وضعیت، پیغام و داده مقداردهی شده و کل آرایه به فرمت جی سان تبدیل شده و به خروجی فرستاده می شود.
توابع Studs و StudsByFid دستوراتی دارند برای خواندن مشخصات دانشجویان از بانک اطلاعاتی، قراردادن رکورد ها در یک آرایه و برگشت دادن آرایه. تابع دوم پارامتر fid را گرفته و دانشجویان را بر اساس fid فیلتر می کند.
در برنامه اصلی ابتدا با دستور file_get_contents داده های فرستاده شده از طرف سرویس گیرنده دریافت شده و تجزیه می شوند و از روی آنها آرایه params ساخته می شود که یک آرایه انجمن است، متغیرهای فرستاده شده اندیس های آن را تشکیل داده و مقادیر آنها داخل آرایه ذخیره شده اند.
سپس بررسی می شود ، اگر پارامتر method که نام تابع درخواستی است فرستاده شده باشد ، به حروف کوچک تبدیل شده و با کلمات studs و studsbyfid مقایسه شده و تابع درخواستی اجرا می شود.
نتیجه برگشتی از این دو تابع، به response فرستاده می شود تا به کلاینت برگشت داده شود.
در هر مرحله در صورت وقوع خطا تابع response فراخوانی می شود و کد وضعیت خطا و پیغام خطا را به کلاینت برگشت خواهد داد.
ساخت برنامه کلاینت برای استفاده از REST API
پس از ساخت برنامه REST API در سمت سرور حالا نوبت می رسد به نوشتن برنامه ای در سمت کلاینت که بتواند از آن استفاده کند. برنامه کلاینت می تواند با هر زبان برنامه نویسی و در هر محیطی نوشته شده و اجرا شود.
ما در این قسمت برای این کار از زبان PHP استفاده کرده ایم ، هر چند قصد داریم نسخه های دیگری با زبان های دیگر هم در آینده بنویسیم.
فایل های سمت کلاینت را می توانید در پوشه جداگانه ای مثلاً با نام client قرار دهیم:
http://127.0.0.1/restapi/client/
در زبان پی اچ پی،براحتی می توان از برنامه نویسی شی گرا و کلاس ها استفاده کرد تا برنامه ها راحت تر نوشته شوند .
ما هم اول یک کلاس بنام APIClient نوشتیم که امکاناتی برای ارسال درخواست از سرور دارد , نیز از فایل stud-list1.php که برای درخواست لیست همه دانشجویان و فایل stud-list2.php که برای درخواست دانشجویان بر اساس رشته درخواستی و نمایش آنها در قالب جدول استفاده شده است:
http://127.0.0.1/restapi/client/api-client.php
http://127.0.0.1/restapi/client/stud-list1.php
http://127.0.0.1/restapi/client/stud-list2.php
محتوای فایل api-client.php
<?php
class APIClient{
protected $url="http://127.0.0.1/restapi/server/api.php";
public function APIClinet($url=""){
if($url!="") $this->url=$url;
}
public function request( $params)
{
$query=http_build_query($params);
$client=curl_init();
curl_setopt($client , CURLOPT_URL , $this->url );
curl_setopt($client , CURLOPT_POST , 1 );
curl_setopt($client , CURLOPT_POSTFIELDS , $query );
curl_setopt($client , CURLOPT_RETURNTRANSFER , true );
$res= curl_exec($client);
curl_close($client);
//echo $res;exit;
$res= json_decode($res);
return $res;
}
}
?>
محتوای فایل stud-list1.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
<table width="600" border="1">
<tbody>
<tr>
<td>Sid</td>
<td>Name</td>
<td>Average</td>
<td>Fid</td>
</tr>
<?php
include("api-client.php");
$api=new APIClient();
$params['method']="studs";
$res=$api->request($params);
if($res->status) {
$rows=(array)$res->data;
foreach($rows as $row) {
?>
<tr>
<td><?php echo $row->sid; ?></td>
<td><?php echo $row->name; ?></td>
<td><?php echo $row->avgr; ?></td>
<td><?php echo $row->fid; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
} else echo "<h2>".$res->message."</h2>";
?>
</body>
</html>
نتیجه اجرای برنامه کلاینت stud-list1.php:
محتوای فایل stud-list2.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head><body>
<form action="" method="post">
Field: <input type="text" name="fid" >
<input type="submit" value="Show" >
</form>
<?php
if(isset($_POST['fid'])) :
?>
<table width="600" border="1">
<tbody>
<tr>
<td>Sid</td>
<td>Name</td>
<td>Average</td>
<td>Fid</td>
</tr>
<?php
include("api-client.php");
$api=new APIClient();
$params['method']="studsbyfid";
$params['fid']=$_POST['fid'];
$res=$api->request($params);
if($res->status) {
$rows=(array)$res->data;
foreach($rows as $row) {
?>
<tr>
<td><?php echo $row->sid; ?></td>
<td><?php echo $row->name; ?></td>
<td><?php echo $row->avgr; ?></td>
<td><?php echo $row->fid; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
} else echo "<h2>".$res->message."</h2>";
endif; ?>
</body>
</html>