المحتوى عن 'lumen'.



مزيد من الخيارات

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المُحتوى


التصنيفات

  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • نصائح وإرشادات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • مقالات عامة
  • التجارة الإلكترونية

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
  • HTML5
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • سي شارب #C
    • منصة Xamarin
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • برمجة أندرويد
  • لغة R
  • سير العمل
    • Git
  • صناعة الألعاب
    • Unity3D
  • مقالات عامّة

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • مقالات عامّة

التصنيفات

  • خواديم
    • الويب HTTP
    • قواعد البيانات
    • البريد الإلكتروني
    • DNS
    • Samba
  • الحوسبة السّحابية
    • Docker
  • إدارة الإعدادات والنّشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • مقالات عامة

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات

التصنيفات

  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • مقالات عامة

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
  • أندرويد
  • iOS
  • macOS
  • ويندوز

التصنيفات

  • شهادات سيسكو
    • CCNA
  • شهادات مايكروسوفت
  • شهادات Amazon Web Services
  • شهادات ريدهات
    • RHCSA
  • شهادات CompTIA
  • مقالات عامة

أسئلة وأجوبة

  • الأقسام
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة البرمجة
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات
    • أسئلة الشهادات المتخصصة

التصنيفات

  • ريادة الأعمال
  • العمل الحر
  • التسويق والمبيعات
  • البرمجة
  • التصميم
  • DevOps

تمّ العثور على 3 نتائج

  1. Lumen هو إطار عمل مصغّر Micro-framework مبني باستخدام إطار العمل Laravel، وهما من صنع Taylor Otwell. صُمّم Lumen لتطوير الخدمات المصغّرة مثل التطبيقات الصغيرة أو خدمات الويب، والهدف من تطويره هو الحصول على أقصى قدر من السرعة، فقد تم استبدال مكوّن التوجيه Symfony في Laravel بـ FastRoute في Lument لتحسين الأداء وزيادة السرعة. في هذا الدرس سننشئ واجهة برمجية بنمط RESTful، وستعمل هذه الواجهة البرمجية على تخزين وعرض المعلومات الخاصّة بالكتب. تثبيت Lumen سنستخدم Composer لتثبيت lumen، لذا سنتحقّق من وجود هذه المكتبة في النظام، وذلك بكتابة الأمر التالي في الطرفية أو في سطر الأوامر: composer إن ظهرت أوامر Composer فهذا يعني أنّه مثبت في الجهاز، أمّا في حالة عدم تثبيت Composer يمكنك الاطلاع على طريقة التثبيت في هذا المقال. بعد تثبيت composer توجّه إلى المجلّد الجذر في الخادوم: cd /var/www/html لمستخدمي نظام ويندوز سنفترض أن المستخدم يمتلك نسخة من خادوم Wamp في الجهاز، لذا يمكن التوجّه إلى المجلّد الجذر في الخادوم بواسطة الأمر التالي: cd wamp\www والآن سنخبر composer بأنّ ينشئ مشروع Lumen باسم “lumen_rest_ce” باستخدام حزمة “laravel/lumen”: composer create-project laravel/lumen lumen_rest_ce سينشئ هذا الأمر مجلّدًا باسم “lumen_rest_ce” ويثبت جميع ملفّات إطار العمل Lumen إضافة إلى جميع الاعتماديات المتعلّقة به. أداة Artisan موجودة في Lumen كما هو الحال في Laravel، ولكنّها تدعم عددًا أقلّ من الأوامر، ويمكنك الاطلاع على قائمة الأوامر بكتابة الأمر التالي في سطر الأوامر: php artisan لاحظ أنّ الأمر serve والمسؤول عن تشغيل التطبيق على الخادوم غير متوفّر في Lumen لذا سنستعين بخادوم التطوير الخاصّ بلغة PHP لتشغيل Lumen وكما يلي: php -S localhost:8000 -t public افتح المتصفّح الآن وتوجّه إلى العنوان localhost:8000. إن ظهر لك رقم الإصدار الخاص بـ Lumen فهذا يعني أنّ عملية التثبيت قد تمّت بنجاح. الإعدادات أنشئ قاعدة بيانات mysql باستخدام phpmyadmin أو أي عميل Mysql آخر، ثمّ عدّل ملف إعدادات Lumen في مجلد المشروع والذي يحمل الاسم “lumen_rest_ce/.env” بالصورة التالية: DB_CONNECTION=mysql DB_HOST=localhost DB_DATABASE=lumen_rest_ce DB_USERNAME=root DB_PASSWORD=your_password افتح الملف lumen_rest_ce/bootstrap/app.php وأزل علامات التعليق من السطرين التاليين: $app->withFacades(); $app->withEloquent(); إزالة التعليق عن هذين السطرين يسمح لنا باستخدام فئة Facade و Eloquent ORM في مشروعنا. التهجير Migration سنكتب الآن مخطّط قاعدة البيانات ونهيّئه لعملية التهجير، حيث سننشئ جدولًا باسم book يتضمّن ستة أعمدة. المعرّف id (قيمته رقمية int وتتزايد تلقائيًا)، العنوان title (من نوع varchar) الكاتب author (من نوع varchar)، الرقم المعياري الدولي للكتاب isbn (من نوع varchar) وحقلي تاريخ الإنشاء وتاريخ التعديل. سنستخدم عملية التهجير والتي هي بمثابة نظام إدارة نسخ خاصّ بقواعد البيانات. اكتب الأمر التالي في سطر الأوامر: php artisan make:migration create_books_table --create=books سينشئ هذا الأمر ملف تهجير في المجلد dbaatase/migration. يتضمّن هذا الملف صنفًا يحمل الاسم CreateBooksTable والذي يضمّ بدوره تابعين الأول هو up حيث سنكتب مخطّط البيانات، أما الآخر فهو down وهو التابع المسؤول عن حذف الجدول. عدّل الملف ليصبح بالصورة التالية: use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateBooksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('books', function(Blueprint $table) { $table->increments('id'); $table->string('title'); $table->string('author'); $table->string('isbn'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('books'); } } لإنشاء الجدول في قاعدة البيانات سنحتاج إلى تهجير أو تنفيذ ملف التهجير الذي أنشأناه قبل قليل وذلك بواسطة الأمر التالي: php artisan migrate النموذج Model أنشئ الآن نموذج Book ضمن الملف app/Book.php وأضف إليه الشيفرة التالية: <?php namespace App; use Illuminate\Database\Eloquent\Model; class Book extends Model { protected $fillable = ['title', 'author', 'isbn']; } ?> أنشئ كذلك ملفّ المتحكّم BookController.php في المجلد app/Http/Controllers وأضف إليه الشيفرة التالية: <?php namespace App\Http\Controllers; use App\Book; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class BookController extends Controller{ ..... ..... } ?> التوجيه Routing افتح الملف web.php في المجلد routes وستجد أنّه يتضمن مسارًا معرّفًا مسبقًا: $app->get('/', function() use ($app) { لغرض كتابة واجهة برمجية بنمط RESTful سنحتاج إلى كتابة المزيد من المسارات وتوابع المتحكّمات المرتبطة بها، وحسب الجدول التالي: التابع عنوان Url Controller@method GET /api/v1/book BookController@index جميع الكتب GET {api/v1/book/{id BookController@getbook إحضار الكتاب حسب المعرّف id POST /api/v1/book BookController@createBook إنشاء سجل جديد في الجدول PUT {api/v1/book/{id BookController@updateBook تحديث الكتاب حسب المعرّف id DELETE {api/v1/book/{id BookController@deleteBook حذف الكتاب حسب المعرّف id لاحظ أنّنا أضفنا v1 إلى جميع المسارات ونقصد به الإصدار الأول، وهذا من الممارسات التي ينصح باتباعها عند إنشاء خدمات الويب. حسب الجدول السابق فإن ملف web.php سيبدو كالتالي: $app->get('/', function() use ($app) { return 'Lumen RESTful API By Hsoub Academy (<a class="vglnk" href="https://academy.hsoub.com" rel="nofollow"><span>https</span><span>://</span><span>academy.hsoub</span><span>.</span><span>com</span></a>)'; }); $app->get('api/v1/book','App\Http\Controllers\BookController@index'); $app->get('api/v1/book/{id}','App\Http\Controllers\BookController@getbook'); $app->post('api/v1/book','App\Http\Controllers\BookController@createBook'); $app->put('api/v1/book/{id}','App\Http\Controllers\BookController@updateBook'); $app->delete('api/v1/book/{id}','App\Http\Controllers\BookController@deleteBook'); يمكننا كذلك تجميع المسارات حسب لاحقة معيّنة أو حسب نطاقات الأسماء، وبهذا لن نكون بحاجة إلى إضافة api/vi ولا إلى كتابة App\Http\Controllers في جميع المسارات. عدّل الشيفرة السابقة لتصبح بالصورة التالية: $app->get('/', function() use ($app) { return 'Lumen RESTful API By Hsoub Academy (<a class="vglnk" href="https://academy.hsoub.com" rel="nofollow"><span>https</span><span>://</span><span>academy.hsoub</span><span>.</span><span>com</span></a>)'; }); $app->group(['prefix' => 'api/v1','namespace' => 'App\Http\Controllers'], function($app) { $app->get('book','BookController@index'); $app->get('book/{id}','BookController@getbook'); $app->post('book','BookController@createBook'); $app->put('book/{id}','BookController@updateBook'); $app->delete('book/{id}','BookController@deleteBook'); }); المتحكّم والآن عدّل الملف BookController.php وأضف إليه التوابع التي عرّفناها في ملف web.php السابق: <?php namespace App\Http\Controllers; use App\Book; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class BookController extends Controller{ public function index(){ $Books = Book::all(); return response()->json($Books); } public function getBook($id){ $Book = Book::find($id); return response()->json($Book); } public function createBook(Request $request){ $Book = Book::create($request->all()); return response()->json($Book); } public function deleteBook($id){ $Book = Book::find($id); $Book->delete(); return response()->json('deleted'); } public function updateBook(Request $request,$id){ $Book = Book::find($id); $Book->title = $request->input('title'); $Book->author = $request->input('author'); $Book->isbn = $request->input('isbn'); $Book->save(); return response()->json($Book); } } اختبار الواجهة البرمجية أصبحت الواجهة البرمجية جاهزة الآن للاختبار، وسنستخدم الأداة CURL لإجراء الاختبار: curl -I <a class="vglnk" href="http://localhost:8000/api/v1/book" rel="nofollow"><span>http</span><span>://</span><span>localhost</span><span>:</span><span>8000</span><span>/</span><span>api</span><span>/</span><span>v1</span><span>/</span><span>book</span></a> curl -v -H "Accept:application/json" <a class="vglnk" href="http://localhost:8000/api/v1/book/2" rel="nofollow"><span>http</span><span>://</span><span>localhost</span><span>:</span><span>8000</span><span>/</span><span>api</span><span>/</span><span>v1</span><span>/</span><span>book</span><span>/</span><span>2</span></a> curl -i -X POST -H "Content-Type:application/json" <a class="vglnk" href="http://localhost:8000/api/v1/book" rel="nofollow"><span>http</span><span>://</span><span>localhost</span><span>:</span><span>8000</span><span>/</span><span>api</span><span>/</span><span>v1</span><span>/</span><span>book</span></a> -d '{"title":"Test Title","author":"test author","isbn":"12345"}' curl -v -H "Content-Type:application/json" -X PUT <a class="vglnk" href="http://localhost:8000/api/v1/book" rel="nofollow"><span>http</span><span>://</span><span>localhost</span><span>:</span><span>8000</span><span>/</span><span>api</span><span>/</span><span>v1</span><span>/</span><span>book</span></a> -d '{"title":"Test updated title","author":"test upadted author","isbn":"1234567"}' curl -i -X DELETE <a class="vglnk" href="http://localhost:8000/api/v1/book/2" rel="nofollow"><span>http</span><span>://</span><span>localhost</span><span>:</span><span>8000</span><span>/</span><span>api</span><span>/</span><span>v1</span><span>/</span><span>book</span><span>/</span><span>2</span></a> تتيح الإضافة Postman إجراء الاختبارات على الواجهات البرمجية بنمط RESTful وبسهولة. بعد تثبيت هذه الإضافة توجّه في متصفح Chrome إلى العنوان chrome://apps/ لعرض الإضافات المثبّتة وتشغيل POSTMAN. ختامًا ها قد أصبحت الواجهة البرمجية البسيطة التي أنشأناها جاهزة، ولكن لا زال ينقصها الكثير من الخصائص كالاستثياق والتحقّق من البيانات ومعالجة الأخطاء وغير ذلك الكثير. ترجمة - وبتصرّف - للمقال RESTful API in Lumen, A Laravel Micro Framework لصاحبه Arkaprava Majumder.
  2. اكتشفت مؤخرًا المتعة الكبيرة في استخدام مكتبة [Fractal المقدّمة من PHP League] لإنشاء استجابات للواجهات البرمجية التي تعطي مخرجات من نوع JSON وذلك عند العمل على نماذج Eloquent في إطاري العمل Laravel و Lumen للحصول على المخرجات التي أرغب بها. هذه الحزمة مشابهة إلى حدٍّ كبير لمكتبة ActiveModel Serializer في إطار العمل Rails، إذ إنّها تتيح لك التحكّم الدقيق بالمخرجات التي ترغب في وصولها إلى المستخدم، إضافة إلى أنّها تفصل الشيفرة المسؤولة عن إنشاء كائن JSON عن نموذج Eloquent وهذا أمر في غاية الأهمية. والآن بعد أن أتيح لي تطوير عدد من الواجهات البرمجية لفترة زمنية لا بأس بها، خطر لي أن أتحدّث عن الطرق التي اتبعتها في ربط Fractal مع تطبيقات Laravel و Lumen (تختلف طريقة الربط في إطار Lumen لأنّه لا يدعم ماكروات Response). المُسَلسِلات المخصّصة Costum Serializers بادئ ذي بدء، تدعم Fractal عددًا من المُسَلسِلات Serializers لتكوين بنية خاصة بالاستجابة، وتستخدم بصورة افتراضية المسَلسِل الذي يدعى بـ DataArraySerializer والذي يضيف مفتاح جذر root key يحمل الاسم data إلى الاستجابة، لذا إن كنت لا تمانع من استخدام هذا المُسَلسِل فيمكنك تجاوز هذه الخطوة. أما لو كنت ترغب في استخدام مُسَلسِل آخر فعليك تسجيل الصنف Manager مع حاوية IoC في مزوّد الخدمة AppServiceProvider أو في مزوّد خدمة آخر إن كنت ترى أنّه يناسبك أكثر، ولكن عليك الانتباه إلى أنّ دعم JSON-API غير مكتمل حتى الآن (المقالة الأصلية نشرت سنة 2015. (المترجم)). public function register() { $this->app->bind('League\Fractal\Manager', function($app) { $manager = new \League\Fractal\Manager; // Use the serializer of your choice. $manager->setSerializer(new \App\Http\Serializers\RootSerializer); return $manager; }); } إنشاء المحوّلات Transformers بعد ذلك سنحتاج إلى إنشاء بعض المحوّلات - محوّل لكل نوع من أنواع نماذج Eloquent التي ترغب في تخريجها بواسطة الواجهة البرمجية - وفي مثالنا هذا سأستخدم مدوّنة حيث يضمّ النموذج AppUser عددًا من نماذج AppPost وسنعرض المستخدم مع المقالات الخاصّة به. أنشأت مجلّدً للتحويلات داخل مجلّد Http: app/Http/Transoformers، والآن يمكنني إنشاء محوّلين، الأول لنموذج User والثاني لنموذج Post. محوّل المستخدمين User سيكون سهلًا، إذ أنّه سيُرجع الحقول المطلوبة من قبل واجهتي البرمجية. في هذا المثال، يمتلك النموذج User خاصّية is_admin وهي عبارة عن قيمة منطقية boolean. ويمكنني التعبير عن ذلك في المحوّل بواسطة العبارة (bool) $user->is_admin ولكن اعتبارًا من الإصدار 5.0 وما بعده من Laravel أصبح بالإمكان استخدام خاصّية $casts في النموذج وسيكون Eloquent قادرًا بعدها على معالجة عملية الوصف بالنيابة عنك. يستحسن معالجة مثل هذه الأمور ضمن النموذج لأنّها ستكون متاحة في التطبيق برمّته. <?php namespace App\Http\Transformers; use App\User; use League\Fractal\TransformerAbstract; class UserTransformer extends TransformerAbstract { /** * Turn this item object into a generic array. * * @param \App\User $user * @return array */ public function transform(User $user) { return [ 'id' => $user->id, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'email' => $user->email, 'is_admin' => $user->is_admin, 'created_at' => $post->created_at->toDateTimeString(), 'updated_at' => $post->updated_at->toDateTimeString() ]; } } بما أنّ خصائص التاريخ في نماذج Eloquent هي نسخ من مكتبة Carbon يمكن إذًا استخدام الدوال المساعدة التي تقدّمها هذه المكتبة لإرجاع التاريخ بالصيغة التي نرغب بها. وفي مثالنا سنستخدم الدالة toDateTimeString() وسيكون التاريخ بالصيغة التالية: Y-m-d H:i:s (السنة - الشهر - اليوم الساعة:الدقائق:الثواني). والآن سنحتاج إلى محوّل لأجل نموذج Post، وسيكون هذا المحوّل مختلفًا عن السابق لأنّنا نرغب في تضمين النموذج User المرتبط بنموذج Post مع هذه الاستجابة. <?php namespace App\Http\Transforers; use App\Post; use League\Fractal\TransformerAbstract; class PostTransformer extends TransformerAbstract { /** * List of resources possible to include * * @var array */ protected $availableIncludes = ['user']; /** * List of resources to automatically include. * * @var array */ protected $defaultIncludes = ['user']; /** * Turn this item object into a generic array. * * @param \App\Post $post * @return array */ public function transform(Post $post) { return [ 'id' => $post->id, 'title' => $post->title, 'content' => $post->content, 'created_at' => $post->created_at->toDateTimeString(), 'updated_at' => $post->updated_at->toDateTimeString(), 'published_at' => $post->published_at->toDateTimeString() ]; } /** * Include user. * * @param \App\Post $post * @return League\Fractal\ItemResource */ public function includeLevels(Post $post) { return $this->item($post->user, new UserTransformer); } } لاحظ أنّه بالإمكان إرجاع $this->collection داخل المحوّل إن كنت ترغب في ربط مجموعة بدل من عنصر واحد. إنشاء الاستجابات في Laravel عادة ما أنشئ مزوّد خدمة Fractal FractalServiceProvider والذي يضمّ التابع register() الذي قمت بوصفه سابقًا، ثم أسجّل بعض الماكروات في التابع boot() كما تلاحظ هنا. سيؤدي ذلك إلى إضافة تابعين إضافيين إلى معمل (factory) Response في Laravel وسيسهّل إرجاع الاستجابات على هيئة عناصر أو مجموعات. لاحظ أنّي حدّدت نوع (type hint) المحوّل ليكون نسخة من الصنف TransformerAbstract وذلك لأنّي أنشئ دائمًا المحوّلات من الاستجابات بدلًا من صيغة الدالة المغلقة closure لأنّي أرى بأنّ هذه الطريقة ستحافظ على ترتيب الشيفرات التي أكتبها. لكن إن كنت تفضل استخدام الدوال المغلقة بدلًا من المحوّلات فيمكنك بكل ساطة أن لا تحدد نوع المحوّل ضمن المعاملات. public function boot() { $fractal = $this->app->make('League\Fractal\Manager'); response()->macro('item', function ($item, \League\Fractal\TransformerAbstract $transformer, $status = 200, array $headers = []) use ($fractal) { $resource = new \League\Fractal\Resource\Item($item, $transformer); return response()->json( $fractal->createData($resource)->toArray(), $status, $headers ); }); response()->macro('collection', function ($collection, \League\Fractal\TransformerAbstract $transformer, $status = 200, array $headers = []) use ($fractal) { $resource = new \League\Fractal\Resource\Collection($collection, $transformer); return response()->json( $fractal->createData($resource)->toArray(), $status, $headers ); }); } والآن أصبح من السهل إنشاء استجابة واحدة (لمستخدم واحد مثلًا) ومجموعة من الاستجابات (لجميع مقالات المدوّنة مثلًا). /** * GET /users/1 * * @param int $userId * @return \Illuminate\Http\Response */ public function showUser($userId) { $user = \App\User::findOrFail($userId); return response()->item($user, new \App\Http\Transformers\UserTransformer); } /** * GET /posts * * @return \Illuminate\Http\Response */ public function showPosts() { $posts = \App\Post::with('user')->get(); return response()->collection($posts, new \App\Http\Transformers\PostTransformer); } إن كنت ترغب في استخدام حالة استجابة HTTP أخرى مثل 201 (تم الإنشاء) أو 204 (لا يوجد محتوى) يمكنك وبكل سهولة تمرير رمز الحالة كمعامل ثالث إلى الماكرو. إنشاء الاستجابات في Lumen يتطلّب إنشاء الاستجابات في Lumen اتباع أسلوب مختلف قليلًا؛ ذلك لأنّ Lumen لا يدعم الماكروات في معمل Response؛ لذا سأضيف هذه التوابع إلى المتحكّم الرئيسي في الواجهة البرمجية. /** * Create the response for an item. * * @param mixed $item * @param \League\Fractal\TransformerAbstract $transformer * @param int $status * @param array $headers * @return Response */ protected function buildItemResponse($item, \League\Fractal\TransformerAbstract $transformer, $status = 200, array $headers = []) { $resource = new \League\Fractal\Resource\Item($item, $transformer); return $this->buildResourceResponse($resource, $status, $headers); } /** * Create the response for a collection. * * @param mixed $collection * @param \League\Fractal\TransformerAbstract $transformer * @param int $status * @param array $headers * @return Response */ protected function buildCollectionResponse($collection, \League\Fractal\TransformerAbstract $transformer, $status = 200, array $headers = []) { $resource = new \League\Fractal\Resource\Collection($collection, $transformer); return $this->buildResourceResponse($resource, $status, $headers); } /** * Create the response for a resource. * * @param \League\Fractal\Resource\ResourceAbstract $resource * @param int $status * @param array $headers * @return Response */ protected function buildResourceResponse(\League\Fractal\Resource\ResourceAbstract $resource, $status = 200, array $headers = []) { $fractal = app('League\Fractal\Manager'); return response()->json( $fractal->createData($resource)->toArray(), $status, $headers ); } يمكنك الآن استدعاء أي تابع من هذه التوابع في أي متحكّم موروث من هذا المتحكّم لإنشاء نفس الاستجابات التي أنشأناها مع Laravel. return $this->buildItemResponse($user, new \App\Http\Transformers\UserTransformer); return $this->buildCollectionResponse($posts, new \App\Http\Transformers\PostTransformer); ترجمة - وبتصرّف - للمقال Using Fractal with Laravel and Lumen لصاحبه Dwight Conrad Watson.
  3. هذا الدّرس هو جزء من سلسلة دروس حول نشر تطبيقات PHP باستخدام Ansible على Ubuntu، تحدّثنا في الأجزاء الأولى عن الخطوات الأساسيّة لنشر تطبيق، وفي بقيّة الأجزاء تكلمنا عن مواضيع أكثر تقدّمًا مثل قواعد البيانات، عفاريت الطابور queue daemons، وجدولة المهام (عبر cron). سنقوم في هذا الدّرس بالبناء على ما تعلمناه في الدروس السابقة عن طريق تحويل playbook في Ansible من دعمها لتطبيق واحد إلى دعمها لنشر تطبيقات PHP متعدّدة على خادوم أو عدّة خواديم. سنستخدم تطبيقات Lumen بسيطة كجزء أمثلتنا، ولكن يُمكِن تعديل هذه التعليمات بسهولة لتدعم أطر عمل وتطبيقات أخرى في حال كانت متواجدة لديك، من المفضّل أن تستخدم تطبيقات الأمثلة حتى تجد نفسك متآلفًا مع القيام بالتغييرات لِـ playbook. الخطوة الأولى – إضافة المزيد من التطبيقاتفي هذه الخطوة سنقوم بإعداد تطبيقين إضافيين في الـ playbook لدينا. الآن وقد أعدنا تصنيع الـ playbook سنستخدم متغيرات لتعريف التطبيقات، إنّ عملية إضافة تطبيقات جديدة لخادومنا هي عملية سهلة جدًّا، نقوم بإضافتها ببساطة إلى قائمة المتغيرات applications، وهنا تظهر قوة متغيرات Ansible. نفتح playbook من أجل تحريرها: nano php.yml نبحث في أعلى القسم vars عن الكتلة applications: Existing applications variable in php.yml applications: - name: laravel domain: laravel.example.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example نضيف تطبيقين اثنين: Updated applications variable in php.yml applications: - name: laravel domain: laravel.example.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example - name: one domain: one.example.com repository: https://github.com/do-community/do-ansible-php-example-one.git branch: master - name: two domain: two.example.com repository: https://github.com/do-community/do-ansible-php-example-two.git branch: master نحفظ الـ playbook ونقوم بتشغيلها: ansible-playbook php.yml --ask-sudo-pass قد تستغرق هذه الخطوة بعض الوقت بينما يقوم الـ composer بإعداد التطبيقات الجديدة، وعندما ينتهي سنلاحظ تغيير عدد من المهام، وإن دققنا أكثر سنلاحظ أنّه سيتم عرض كل عنصر ناتج عن الحلقة، يخبرنا الأول وهو تطبيقنا الأصل بعبارة ok أو skipped، بينما يخبرنا التطبيقان الجديدان بالحالة changed. والأهم من ذلك أنّه إذا زرنا النطاقات الثلاثة لمواقعنا التي أعددناها في متصفح الإنترنت فينبغي أن نلاحظ ثلاثة مواقع مختلفة. الأول يبدو مألوفًا لنا، أما الموقعان الآخران سيعرضان: http://one.example.com/ This is example app one! http://two.example.com/ This is example app two! وبذلك قمنا بنشر تطبيقي ويب جديدين عن طريق تحديث قائمة التطبيقات ببساطة. الخطوة الثانية – استخدام متغيرات المضيفين Host Variablesسنستخرج في هذه الخطوة متغيراتنا إلى متغيرات المضيفين. بالرجوع إلى الوراء نجد أنّ متغيرات الـ playbook جيدة، ولكن ماذا لو أردنا نشر تطبيقات مختلفة على خواديم مختلفة باستخدام نفس الـ playbook؟ نستطيع عمل تحقّق شرطي على كل مهمّة لإيجاد الخادوم الذي يقوم بتشغيل المهمة، أو نستطيع استخدام متغيرات المضيفين، وهي تمامًا كما تبدو عليه: متغيرات تُطبَّق على مضيف معيّن بدلًا من كافّة المضيفين عبر الـ playbook. يمكن تعريف متغيرات المضيف سطريًّا inline بداخل الملف hosts كما فعلنا مع المتغير ansible_ssh_user أو يمكن تعريفها في ملف مخصّص لكل مضيف داخل الدليل host_vars. في البداية نقوم بإنشاء دليل جديد إلى جانب الملف hosts والـ playbook، نقوم بتسمية الدليل بـ host_vars: mkdir host_vars نحتاج بعدها إلى إنشاء ملف من أجل المضيف، الاتفاقية التي تستخدمها Ansible هي من أجل أن يتوافق اسم الملف مع اسم المضيف في الملف hosts، لذلك على سبيل المثال إن كان يبدو الملف hosts لدينا كما يلي: Ansible hosts file your_first_server_ip ansible_ssh_user=sammy فينبغي أن نقوم بإنشاء ملف يُدعى host_vars/your_first_server_ip، فلنقم بإنشائه الآن: nano host_vars/your_first_server_ip تستخدم ملفّات المضيفين YAML من أجل تنسيقها تمامًا كما هو الحال مع الـ playbooks، ويعني هذا أنّنا نستطيع نسخ القائمة applications إلى ملف المضيفين الجديد لدينا بحيث يبدو كما يلي: New host_vars/your_first_server_ip file --- applications: - name: laravel domain: laravel.example.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example - name: one domain: one.example.com repository: https://github.com/do-community/do-ansible-php-example-one.git branch: master - name: two domain: two.example.com repository: https://github.com/do-community/do-ansible-php-example-two.git branch: master نقوم بحفظ ملف المضيفين الجديد ونفتح الـ playbook لتحريرها: nano php.yml نحدّث أعلى الملف لإزالة كامل القسم applications: Updated top of php.yml --- - hosts: php sudo: yes vars: wwwuser: www-data tasks: . . . نحفظ الـ playbook ونقوم بتشغيلها: ansible-playbook php.yml --ask-sudo-pass وعلى الرغم من أنّنا نقلنا متغيراتنا من الـ playbook إلى ملف المضيفين فيجب أن يبقى الخرج نفسه ولا يجب أن يتم تبليغنا عن تغييرات من قبل Ansible، وكما نرى يعمل host_vars بنفس الطريقة التي يعمل بها vars في الـ playbook، ولكنّه مُخصّص للمضيف. ستكون المتغيرات المُعرّفة في ملفّات host_vars قابلة للوصول عبر كامل الـ playbooks التي تدير الخادوم، وهو مفيد من أجل الخيارات والإعدادات الشائعة، ومع ذلك كن حذرًا من استخدام اسم شائع قد يعني أشياء مختلفة عبر الـ playbooks المختلفة. الخطوة الثالثة – نشر التطبيقات على خادوم آخرسنستخدم في هذه الخطوة ملفات المضيفين الجديدة وننشر تطبيقاتنا على خادوم آخر. نحتاج في البداية إلى تحديث ملف المضيفين hosts بمضيفنا الجديد، نفتحه من أجل تحريره: nano hosts ونقوم بإضافة المضيف الجديد: Ansible hosts file your_first_server_ip ansible_ssh_user=sammy your_second_server_ip ansible_ssh_user=sammy نحفظ الملف ونغلقه. نحتاج بعدها إلى إنشاء ملف مضيفين جديد، كما فعلنا مع أول ملف: nano host_vars/your_second_server_ip تستطيع انتقاء واحد أو أكثر من تطبيقات مثالنا وإضافتها إلى ملف المضيف لديك، فإذا أردت مثلًا نشر مثالنا الأصلي والمثال الثاني إلى خادوم جديد فيجب أن تستخدم: New host_vars/your_second_server_ip file --- applications: - name: laravel domain: laravel.example2.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example - name: two domain: two.example2.com repository: https://github.com/do-community/do-ansible-php-example-two.git branch: master نقوم بحفظ playbook. وأخيرًا نقوم بتشغيلها: ansible-playbook php.yml --ask-sudo-pass ستستغرق Ansible وقتًا ليتم تشغيلها لأنّها تقوم بإعداد كل شيء على خادومنا الثاني، وعندما تنتهي نفتح تطبيقاتنا التي اخترناها في المتصفح (استخدمنا في هذا المثال laravel.example2.com وtwo.example2.com) وللتأكد من أنّه تم إعدادها بشكل صحيح يجب أن نرى التطبيقات المحدّدة التي اخترناها من أجل ملف المضيفين، وينبغي ألّا تحدث أيّة تغييرات على خادومنا الأصلي. الخاتمةأخذنا في هذا الدرس playbook تطبيق وحيد تعمل بشكل كامل وقمنا بتحويلها لتدعم تطبيقات متعددة عبر عدّة خواديم، وبجمعها مع المواضيع التي تمت تغطيتها في الدروس السابقة يجب أن تمتلك كل ما تحتاجه لكتابة playbook كاملة لنشر تطبيقاتك، وكما هو الحال مع الدروس السابقة فلا زلنا لم نسجل الدخول بشكل مباشر باستخدام SSH. ومن المؤكد أنك لاحظت مدى بساطة إضافة المزيد من التطبيقات والمزيد من الخواديم بعد الانتهاء من تجهيز بنية الـ playbook، وهنا تكمن قوة Ansible وهو ما يجعلها مرنة جدًّا وسهلة الاستخدام. ترجمة -وبتصرّف- لـ How To Deploy Multiple PHP Applications using Ansible on Ubuntu 14.04 لصاحبه Stephen Rees-Carter.