REST API على Laravel في 100 سطر من التعليمات البرمجية

inb4: نسخ لصق من الوثائق


يركز الدليل على النشر السريع لمجموعة صغيرة من أجل تطوير واجهة برمجة تطبيقات كاملة وفقًا لأفضل الممارسات ، مأخوذة من وثائق Laravel 5.7 ، التي تم جمعها في مكان واحد. كتبت لنفسي ولزملائي كغش ، أتمنى أن يكون مفيدًا لشخص آخر.


مسبقا


نضع إطار عمل


composer create-project --prefer-dist laravel/laravel scaffold-api


إزالة مكونات واجهة المستخدم غير الضرورية (vuejs ، رد فعل)


php artisan preset none


تكوين اتصال قاعدة البيانات


انتقل إلى المجلد ، قم بتحرير ملف .env:


 DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=api-authentification DB_USERNAME=root DB_PASSWORD= 

البدء في توليد


ننفذ في وحدة التحكم
php artisan make:model Game -mrc


نحصل على النموذج والهجرة والتحكم:


 Model created successfully. Factory created successfully. Created Migration: 2019_02_27_105610_create_games_table Controller created successfully. 

إنشاء أعمدة في جدول قاعدة البيانات


نقوم بتصحيح عملية الترحيل عن طريق إضافة أعمدة إلى الجدول. الأنواع الأكثر استخدامًا:


  • increments('id')
  • string('title')
  • text('description')
  • tinyInteger('complexity')
  • boolean('isActive')
  • softDeletes()

للحقول الاختيارية ، لا تنسَ إضافة القيمة الافتراضية بـ ->default()


تطبيق الهجرات عن طريق تشغيل php artisan migrate


نقوم بإنشاء قواعد التحقق من الصحة


تشغيل php artisan make:request GameRequest


افتح App/Http/Requests/GameRequest.php .
في طريقة authorize() ، عيّن return true حتى نضيف التفويض.
تصف المصفوفة التي يتم إرجاعها في طريقة rules() القواعد الخاصة بجميع الأعمدة التي أدرجناها في عملية الترحيل. القواعد المتاحة هنا


لتقليل التعليمات البرمجية ، نستخدم إنشاء رمز التبديل لأفعال http مختلفة ، بدلاً من القيام StoreGameRequest منفصلة أو UpdateGameRequest ، إلخ.


 public function rules(Request $request) { $rules = [ 'title' => 'required|string|unique:games,title', 'description' => '', 'complexity' => 'required|min:1|max:10', 'minPlayers' => 'required|min:1|max:10', 'maxPlayers' => 'required|min:1|max:10', 'isActive' => 'required|boolean' ]; switch ($this->getMethod()) { case 'POST': return $rules; case 'PUT': return [ 'game_id' => 'required|integer|exists:games,id', // .   : unique:games,id,' . $this->route('game'), 'title' => [ 'required', Rule::unique('games')->ignore($this->title, 'title') //  ,     ] ] + $rules; //      // case 'PATCH': case 'DELETE': return [ 'game_id' => 'required|integer|exists:games,id' ]; } } 

خيارات وصف خطأ مخصصة


إذا كنت بحاجة إلى نصوص خطأ خاصة بك ، فإننا نعيد تعريف طريقة الرسائل () ، والتي تُرجع صفيفًا مع ترجمة لكل قاعدة:


 public function messages() { return [ 'date.required' => 'A date is required', 'date.date_format' => 'A date must be in format: Ym-d', 'date.unique' => 'This date is already taken', 'date.after_or_equal' => 'A date must be after or equal today', 'date.exists' => 'This date doesn\'t exists', ]; } 

لضمان عدم توفر المعلمات التي تم تمريرها في نص الطلب فحسب ، ولكن أيضًا المعلمات التي تم تمريرها في عنوان URL في قواعد التحقق من الصحة ، فإننا نعيد تحديد الطريقة بالكامل (التي تستخدم عادةً في وحدة التحكم في شكل $ request-> all ()):


 public function all($keys = null) { // return $this->all(); $data = parent::all($keys); switch ($this->getMethod()) { // case 'PUT': // case 'PATCH': case 'DELETE': $data['date'] = $this->route('day'); } return $data; } 

نحن تكوين وحدة تحكم ووصف منطق العمل


افتح Http\Controllers\GameController . نقوم بإزالة الأساليب التي تم create(), edit() المعدة لتقديم النماذج (نظرًا لأن لدينا REST API ، فهي ليست ضرورية).


استبدال use Illuminate\Http\Request; القياسي use Illuminate\Http\Request; ، على استخدامنا use App\Http\Requests\GameRequest;


بعد ذلك ، قم بتحرير الطرق:


 public function index() { return Game::all(); } 

 public function store(GameRequest $request) { $day = Game::create($request->validated()); return $day; } 

 public function show(Game $game) { return $game = Game::findOrFail($game); } 

 public function update(GameRequest $request, $id) { $game = Game::findOrFail($id); $game->fill($request->except(['game_id'])); $game->save(); return response()->json($game); } 

 public function destroy(GameRequest $request, $id) { $game = Game::findOrFail($id); if($game->delete()) return response(null, 204); } 

إذا كان هناك الكثير من المنطق ، فمن الأفضل وضعه في طبقة منفصلة للخدمة / المستودع


تخصيص النموذج


افتح نموذج التطبيق / Http / Game.php وأضف الخصائص:


 protected $fillable = ['title', 'description', 'complexity', 'minPlayers', 'maxPlayers', 'isActive']; protected $hidden = ['created_at', 'updated_at', 'deleted_at']; 

تكوين الوسيطة


حتى يتمكن تطبيقنا دائمًا من إرجاع json بغض النظر عن الرؤوس التي تم تمريرها ، فإننا نقوم بإنشاء البرامج الوسيطة:


 php artisan make:middleware ForceJsonResponse 

وأضف الكود إليه:


 public function handle($request, Closure $next) { $request->headers->set('Accept', 'application/json'); return $next($request); } 

سجل هذه الوسيطة في app/Http/Kernel.php :


 ... 'api' => [ 'throttle:60,1', 'bindings', \App\Http\Middleware\ForceJsonResponse::class, ], 

نحن تكوين التوجيه


افتح routes/api.php وأضف:


 use Http\Controllers\GameController; Route::apiResource('/games', 'GameController'); 

تستثني طريقة التوجيه :: apiResource الثابتة ، على خلاف طريقة الموارد ، أساليب التحرير وإنشاء ، تاركة فقط الفهرس ، إظهار ، تخزين ، تحديث ، إتلاف.


يمكن تحقيق نفس الشيء مع سجل أكثر وضوحًا:


 Route::resource('/games', 'GameController')->only([ 'index', 'show', 'store', 'update', 'destroy' ]); 

الآن ، يمكنك رؤية المسار باستخدام php artisan route:list command واستخدامه.


واجهة برمجة تطبيقات REST جاهزة!


خاتمة

خاتمة


إذا كنت بحاجة إلى إذن ، فستفعل جواز سفر Laravel القياسي.


تكوين إذن Laravel جواز السفر


 composer require laravel/passport php artisan make:auth php artisan passport:install php artisan migrate 

أضف Laravel\Passport\HasApiTokens إلى طراز App\User Passport::routesmethod في app/AuthServiceProvider :


 public function boot() { $this->registerPolicies(); Passport::routes(); } 

في config/auth.php بتغيير برنامج التشغيل إلى جواز السفر:


 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], 

إنشاء وحدة تحكم للترخيص "php artisan make: controller Api / AuthController.php`


أضف الكود هناك


 use App\User; use Illuminate\Support\Facades\Validator; 

 public function register (Request $request) { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', ]); if ($validator->fails()) { return response(['errors'=>$validator->errors()->all()], 422); } $request['password']=Hash::make($request['password']); $user = User::create($request->toArray()); $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } public function login (Request $request) { $user = User::where('email', $request->email)->first(); if ($user) { if (Hash::check($request->password, $user->password)) { $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } else { $response = "Password missmatch"; return response($response, 422); } } else { $response = 'User does not exist'; return response($response, 422); } } public function logout (Request $request) { $token = $request->user()->token(); $token->revoke(); $response = 'You have been succesfully logged out!'; return response($response, 200); } 

بعد ذلك ، يمكنك استخدام api/register, api/login, api/logout وطرق api/register, api/login, api/logout للتخويل ومنع الوصول إلى api. للقيام بذلك ، نحتاج إلى التفاف توجيه وحدات التحكم REST الخاصة بنا في البرامج الوسيطة:


 Route::middleware('auth:api')->group(function () { ... Route::get('/logout', 'Api\AuthController@logout')->name('logout'); }); 

خاتمة

الكلمة التالية:


لا يزال يتعين إجراء اختبارات وظيفية وإنشاء وثائق في التباهي ، ولكن هذا يتجاوز قليلا نطاق البرنامج التعليمي للسقالة ، وأكثر من ذلك في ذلك الوقت الآخر


Source: https://habr.com/ru/post/ar441946/


All Articles