في المقال السابق تم الحديث عن ما هو RESTful API وكيف يتم عرض البيانات وإستخدام العلاقات، في هذا المقال سوف نتعرف على كيفية إرسال البيانات وحفظها في قاعدة البيانات.
في هذا المثال لدي جدول brand حيث سيتم إضافة حقل name فقط
إنشاء route
في ملف route/api.php نحتاج لإضافة post route حيث يجب أن تكون الـ method من نوع post
Route::post('brand',[BrandController::class,'store']);
إنشاء $fillable
protected $fillable=['name'];
دالة store لحفظ البيانات
public function store(Request $request) { $brand=Brand::create($request->all()); }
كما نلاحظ أنه تم حفظ البيانات وحصلنا على status code = 200 بمعنى أنه تم حفظ البيانات بنجاح.
كما نعلم أنه عند حفظ البيانات دون إستخدام api عادة ما يتم تحويل المستخدم لصفحة أخرى بعد الحفظ مع إظهار رسالة الحفظ، لكن مع إستخدام api فإننا بحاجة لإرجاع البيانات على شكل JSON، وأفضل شيئ يمكن إرجاعه هو object بإستخدام Resource من العنصر الذي تم تخزينة، وللقيام بذلك في دالة store يمكن إستخدام BrandResource الذي تم إنشاؤه في المقالة السابقة.
public function store(BrandStoreRequest $request) { $brand=Brand::create($request->all()); return new BrandResource($brand); }
كما نلاحظ أنه تم إرجاع بيانات على شكل json من العنصر الذي تمت إضافته، لكن status code في هذه الحالة تساوي 201.
كما نلاحظ أن status code يتم إرجاعها بشكل تلقائي، دون أن نقوم نحن بتحديدها، ولمعرفة المزيد عن status code يمكن قرائتها من هذا الموقع https://httpstatuses.com/ ويمكن قرائتها باللغه العربية أيضا من خلال هذه القصاصة https://www.etharshrouf.com/ar/snippets/snippet/42
أفضل طريقة للقيام بعملية التحقق هو إنشاء ملف Request منفصل
ولإنشاء ملف Request لحفظ بيانات brand
php artisan make:request BrandStoreRequest
حيث سيتم إنشاء كلاس باسم BrandStoreRequest في المسار app/http/requests/BrandStoreReuest.php ، وبداخل الدالة return نقوم بكتابة شروط التحقق.
class BrandStoreRequest extends FormRequest { public function authorize() { return true; } public function rules() { return [ 'name'=>'required', ]; } }
كذلك يجب تحويل قيمة الدالة authorize من false إلى true.
ولإستخدام BrandStoreRequest مع الدالة store نقوم بإستبدال Request باسم الكلاس الذي تم إنشاؤه وهو BrandStoreRequest
public function store(BrandStoreRequest $request) { $brand=Brand::create($request->all()); return new BrandResource($brand); }
الأن إذا حاولنا إدخال البيانات دون إدخال قيمة name فإننا سوف نحصل على الخطأ كما بالصورة التالية
من خلال response الذي حصلنا عليه ، نلاحظ ما يلي :
لذلك يجب على مطور front end أو تطبيقات الموبايل الإنتباه لها.
عند إنشاء route لتعديل البيانات يجب الإنتباه لإستخدام الدالة put
إنشاء route
Route::put('brands/{brand}',[BrandController::class,'update']);
وفي دالة تعديل البيانات بداخل BrandController.
public function update(BrandStoreRequest $request, Brand $brand) { $brand->update($request->all()); return new BrandResource($brand); }
لكن الجزء المهم،كما نعلم أنه في أي فورم تعديل بإستخدام blade أنه نقوم بإرسال الدالة @method(‘PUT’) لذلك يجب إرسالها عند إستخدام postman.
إنشاء route
Route::delete('brand/{brand}',[BrandController::class,'destroy']);
دالة حذف البيانات بداخل BrandController
public function destroy(Brand $brand) { $brand->delete(); return response()->noContent(); }
الجزء المهم في دالة الحذف هو إرجاع الـ response بدلا من إرجاع 402 كـ status code يمكن إرجاع
response()->noContent()
والتي تعني 402.
لحذف brand id = 20
كما نلاحظ أيضا أننا بحاجة لإرسال _method=DELETE.
كما نلاحظ في ملف rotute أننا قمنا بإنشاء route لكل method ، لكن يمكن إختصار هذه route في route واحد من خلال إستخدام apiResource
Route::get('brands',[BrandController::class,'index']);
Route::post('brand',[BrandController::class,'store']);
Route::get('products',[ProductController::class,'index']);
Route::get('brands/{brand}',[BrandController::class,'show']);
Route::put('brand/{brand}',[BrandController::class,'update']);
Route::delete('brand/{brand}',[BrandController::class,'destroy']);
يمكن الإستغناء هذه routes لتصبح
Route::apiResource('brands',BrandController::class);
حيث بإستخدام apiResource بشكل تلقائي ستتعامل مع الدوال السبعة بداخل الكونترولر.
كـ backend لا يختلف تحميل الملفات بإستخدام api عن تحميل الملفات دون إستخدام api
لفرض إنه يجب إضافة صورة عند إضافة brand جديد
بداية كما نعلم يجب :-
protected $fillable=['name','photo'];
دالة store بداخل brandController
public function store(BrandStoreRequest $request) { $data=$request->all(); if($request->hasFile('photo')){ $file=$request->file('photo'); $name='brands/'.uniqid().'.'.$file->extension(); $file->storePubliclyAs('public',$name); $data['photo']=$name; } $brand=Brand::create($data); return new BrandResource($brand); }
حيث يمكن أيضا إستخدام postman لرفع الصور
مهند أبوسبيب
السلام عليكم ورحمة الله تعالى وبركاته اولا: جزاك الله خير لما تقدمه من علم نافع باذن الله ثانيا: مجرد ما قمت بعمل BrandStoreRequest صار يظهر لي خطأ في الحفظ وعندما تجاوزتها للتعديل كمان هنالك خطا مع العلم اني اتبعت الخطوات خطوة بخطوة.