تعداد بازدید: 5731

Laravel API Introduction

پیاده سازی سرویسی (WebService API) جهت ارتباط وب اپلیکیشن با کلاینت هایی غیر از مرورگر با زبان عمومی JSON نیازمند پیروی از قوانین خاص می باشد.

هر لینک که به درخواستی از سرور منجر می شود به مثال یک جمله است که فعل آن Http Verb و فاعل آن فاعل آن authentication و مفعول آن Resrource می باشد.

همان طور که پیش تر گفتیم ارتباط کلاینت و سرور از طریق کنترلر انجام می پذیرفت . حال این که زمانی که کلاینت ما Browser بو ما کنترلر داشتیم و الان که کلاینت ما غیر از Browser می باشد نیز کلاینت ما مخصوص API می باشد. برای همین خاطر ما کنترلر های مرتبط با API را در دایرکتوری مجزا قرار می دهیم.

Api Controller

برای ساخت کنترلر برا API ما با اضافه کردن یک Api به مسیر و namespace کنترلر های ایجاد شده آن را مجزا می کنیم. دستوری که برای ساخت کنترلر برای API استفاده می کنیم به شکل زیر می باشد.

مثلا میخواهیم یک کنترلر به ازای Product برای اپلیکیشن بسازیم:

php artisan make:controller Api/ProductController

کنترلر ساخته شده در مسیر app/Http/Controller/Api/ProductController به شکل زیر می باشد.

namespace App\Http\Controllers\Api;

use App\products;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ProductController extends Controller
{
    public function __construct() {}

    public function index() {}

    public function store(StoreRequest $request) {}

    public function show(int $id){}

    public function update(Request $request, int $id) {}

    public function destroy(int $id) {}
}

در ادامه باید به سیستم بفهمانیم که برای اجرای درخواست های api از کنترلر های Api استفاده کند.

نکته : اگرچه کنترلر که رابط کلاینت و سرور می باشد در API متفاوت می باشد اما کل این کنترلر از تمامی امکانات نظیر model , event , queue , … استفاده می کند.

Http Request : درخواستی که باید به سمت کنترلر برای API ارسال می گردد باید هدر های مرتبط را داشته باشد تا سرور از روی آن تشخیص دهد و پاسخ را چه به ازای خطا و چه به ازای پاسخ به شکل اشیاء JSON برگرداند.

'Accept: application/json'
'Content-Type: application/json'

Http Response : اگر هدر های بالا در درخواست کاربر باشد و ما داده از نوع collection را برای کاربر بازگردانیم در آن سمت به صورت JSON کاربر خروجی های ما را دریافت می کند.

همچنین برای ارسال پیام می توانیم از شکل زیر استفاده کنیم :

response()->json(['message'=>'update successfully'],200);

با استفاده از تابع کمکی response می توان پاسخ هایی در قالب json برای کلاینت ارسال کرد. نمونه کامل یک کنترلر با دریافت و ارسال پاسخ برای کلاینت از نوع api را با Resource برابر Product را مرور کنید.

Route api

درخواست کلاینت از Route شروع می گردد. در لاراول برای درخواست ما از دو نوع Route استفاده می کنیم.

  • web : این مورد برای کلاینت WebBrowser استفاده می شود و دارای web middleware می باشد. این میان افزار وجود token را در درخواست ها بررسی می کرد.
  • api : این route میان افزار web را ندارد لذا نیازی به وجود token در بتن درخواست نمی باشد. روش های دیگری برای احراز هویت کاربران در این route وجود دارد که ما می توانیم از آن ها استفاده کنیم.

ما برای Route های مربوط به api نشانه namespace کنترلر مخصوص به خودشان را تعیین کرده ایم. در ابتدای هر Endpoint که برای api route می سازیم api به عنوان prefix داریم . به طور مثال وقتی که تعریف می کنیم :

Route::get('products/{id}', 'ProductController@show');

لینک درخواست به شکل زیر می باشد :

http://localhost:8000/api/products/{id}

مرحله دوم این است که به سیستم بفهمانیم که برای برای route api از کنترلر های Api استفاده کند. برای این کار باید routeServiceProvider را به شکل زیر تغییر دهیم.

namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    protected $WebNamespace = 'App\Http\Controllers';
    protected $ApiNamespace = 'App\Http\Controllers\api';

    public function boot()
    {
        parent::boot();
    }

    public function map()
    {
        $this->mapApiRoutes();
        $this->mapWebRoutes();
    }

    protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->WebNamespace)
             ->group(base_path('routes/web.php'));
    }

    protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->namespace($this->ApiNamespace)
             ->group(base_path('routes/api.php'));
    }
}

همان طور که مشاهده می کنید دو متغیر با نام های WebNamespace و ApiNamespace ساخته ایم که هر یک را در متد های mapWebRoutes و mapApiRoutes استفاده کردیم که namespace های کنترلر های مورد استفاده برای api route , web route می باشد.

API Authentication

برای احراز هویت کاربر می توان از Middleware های مختلفی نظیر auth.basic یا استفاده از پکیج هایی نظیر JWT (Json Web Token) استفاده کرد.

auth.basic : برای استفاده از این روش کافی است که این میان افزار را به route هایی که نیاز است احراز هویت بکنیم بدهیم. این کار می تواند در متد سازنده کنترلر یا route به صورت مستقیم استفاده گردد.

public function __construct()
{
    $this->middleware('auth.basic')->only(['store','update','destroy']);
}
Route::post('products/store','ProductController@store')->middleware(['auth.basic']);

این ساده ترین راه ممکن برای Authentication در API می باشد که به صورتی که کلاینت باید در هدر authorization مقدار encode شده username , password را بفرستد و لاراول هم احراز هویت را انجام می دهد و از آن جا تمامی Auth , auth() به درستی کار می کند. دقت داشته باشید که در این روش به ازای هر درخواست احراز هویت انجام می گردد. یعنی باید کلاینت در هدر Authorization مقدار را بفرستد.

JWT (Json Web Token) : یک پکیج برای احراز هویت (authentication) برای API هایی است که از پروتکل Http استفاده می کنند. نظیر Restfull . این کتابخانه برای فریم ورک Laravel نیز مستنداتی ارائه داده است.

ضمن پیاده سازی مراحل نصب این کتابخانه در لاراول باید به نکات زیر توجه داشت :

  • default gaurd را برای نرم افزار همان web در نظر بگیرید(config/auth.php) . در غیر این صورت سیستم authentication شما برای کلاینت مرورگر به مشکل می خورد.
  • در زمان ساخت AuthController باید زمانی که از تابع کمکی auth استفاده می کنید نوع middleware را به آن معرفی کنید تا کار کند. auth('api')
  • در استفاده از این کتابخانه برای api route برای endpoint ها یا همان عملگر هایی که می خواهید authentication انجام شود حتما از jwt.auth به عنوان middleware استفاده کنید تا policy ها کار کنند.
  • مواردی که گفته شد در پیاده سازی نسخه 1.0 آن روی لاراول 5.7 می باشد. توجه داشته باشید پس از نصب این کتابخانه را به نسخه "tymon/jwt-auth": "^1.0.0-rc.3" بروزرسانی کنید.

نحوه کار این کتابخانه به گونه ای است که کلاینت یک بار از طریق درخواست http://localhost:8000/api/auth/login و ارسال username , password از طریق Entity Body لاگین می کند و در نهایت سرور به کلاینت یک token می دهد که زمان خاصی قابل استفاده می باشد. پس از آن کاربر با ارسال این token به عنوان یک پارامتر از Entity Body یا url Parameter یا ارسال از طریق هدر Authorization خود را احراز هویت کند.

می توان آن را با استفاده از امکانات موجود در AuthController توکن ارسالی را بروزرسانی کرد یا اطلاعاتی در رابطه با درخواست های بر اساس توکن دریافت کرد که در مستندات آن می توانید مشاهده کنید.

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

4 دیدگاه برای Laravel API Introduction

  1. دوست عزیز سلام
    وقتی توکن رو به سرور ارسال کردیم در قسمت بک اند چطور یوزر رو با اکسس توکن احراز هویت کنیم خیلی ممنون میشم اگه راهنمایی کنی

    • با سلام و احترام
      اگر از کتابخانه خاصی برای ساخت توکن استفاده می کنید عملیات احراز هویت رو همون کتابخونه در بطن پروژه برای شما انجام میده ( لازمه که تنظیمات این کتابخونه رو به درستی اعمال کرده باشید) اما اگر توکن رو خودتون میسازید میتونید به ازای هر کاربر یک توکن در پایگاه داده خودتون ذخیره کنید و در درخواست ها با اون توکن احراز هویت رو انجام بدید.

  2. سلام. وقت بخیر. من دو تا پروژه لوکال دارم که هردوشون لاراول هستن و میخوام با استفاده از api فرمم رو توی دیتابیس ذخیره کنم. یکی از این پروژه ها فقط شامل یک فرم هست و پروژه دیگه فقط شامل یک متد store برای ذخیره کردن محتویات در دیتابیس. من نحوه ایجاد کردن api رو با استفاده از مقاله شما یاد گرفتم. منتها نمیدنم چطور باید از پروژه اول به پروژه دوم درخواست بدم؟ مثلا توی فیلد action فرم پروژه اول باید آدرس apiی پروژه دوم رو بنویسم؟ اگه آره توی فیلد action فرم دقیقا چی باید بنویسم؟ یا باید حتما فرم من ajaxی باشه و اونجا باید آدرس api ی پروژه دوم رو بدم؟ در این صورت فیلد url ajax رو دقیقا باید چی بدم؟ یا اصلا باید کار دیگه ای بکنم؟ لطفا راهنماییم کن.

    • با سلام و احترام
      باید آدرس route مربوط به api سایت دوم رو وارد کنید. حال اگر این درخواست از طریق ajax  باشه باید url رو با متد مربوطه و اطلاعاتی که متد api لازم داره بفرستید. اگر خیر می تونید یک Request بفرستید که راه های متفاوتی برای ارسال درخواست با هر متدی که بخواهید هست . می تونید از کتابخونه Guzzle استفاده کنید یا هر کتابخونه دیگه ای یا حتی با استفاده از Curl این کار رو انجام بدید. پیشنهاد میشه ابتدا نحوه ارسال درخواست رو در پروتکل http بررسی کنید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *