مرحبا بالجميع ، اسمي أليكس. أريد أن أعرض لكم إطار عمل PHP الخاص بي لإنشاء خدمات microservices. لقد نشأت عن تجربتي التي قمت بها منذ ثلاث سنوات ، والتي تطورت لاحقًا لتصبح مشروعًا للحيوانات الأليفة ، وفي وقت لاحق في هذا الإطار ، قمت بإنشاء العديد من مشاريع الإنتاج.
عندما بدأت فعل ذلك ، شرعت في اتخاذ قرار:
- يمكن دمجها بسهولة في المشاريع القائمة ؛
- يمكنك إنشاء شيء على الأقل بسرعة العمل ؛
- التصاميم الأكثر إيجازاً وتعبيرية ؛
- تستخدم بحكمة قدرات PHP الحديثة.
إذن من أين تبدأ؟ بالطبع من المصدر! يمكنك مشاهدتها على
جيثبحسنًا ، حتى لا ندخل في حجج طويلة ، فلنبدأ على الفور بمثال عملي.
بادئ ذي بدء ، نحن بحاجة إلى .htaccess ، حيث سنقوم بتكوين عدة قواعد:
# use mod_rewrite for pretty URL support RewriteEngine on RewriteRule ^([a-z0-9A-Z_\/\.\-\@%\ :,]+)/?(.*)$ index.php?r=$1&%{QUERY_STRING} [L] RewriteRule ^/?(.*)$ index.php?r=index&%{QUERY_STRING} [L]
ثم يمكنك إنشاء الخدمة الأولى الخاصة بك. في ذلك ، سوف نجعل نقطة نهاية واحدة ستعمل على معالجة طريقة GET وإرجاع رسالة مفادها أن كل شيء على ما يرام. نوع من الفحص الصحي.
للبدء ، نحتاج إلى توصيل إطار عملنا:
require_once ('vendor/service/service.php');
ثم نقوم بإنشاء فصل لخدمة microservice:
class TodoService extends ServiceBase implements ServiceBaseLogicInterface { }
هنا لدينا:
- ServiceBase هي فئة أساسية من الخدمة ذات الوظائف الأساسية والأكثر فائدة.
- ServiceBaseLogicInterface هي الواجهة التي يحتاج أي فئة إلى تنفيذها إذا كان يريد توفير معالجات نقطة النهاية. في حين أن هذه الواجهة لا تفرض أي متطلبات خاصة على فصلك. قدمت للتو لكتابة أكثر صرامة.
ثم نحصل على معالج نقطة النهاية الأولى:
public function action_ping() { return ('I am alive!'); }
ثم نطلق الخدمة الأولى لدينا:
Service::start('TodoService');
بوضع كل ذلك معا ، نحصل على:
class TodoService extends ServiceBase implements ServiceBaseLogicInterface { public function action_ping() { return ('I am alive!'); } } Service::start('TodoService');
قد ينشأ سؤال معقول - وعلى أي عنوان URL تتوفر هذه الوظيفة؟ الحقيقة هي أنه من خلال تحديد طريقة مع بادئة action_ <name-part> ، أوضحت للخدمة أنها معالج URL <name-part> أي في حالتنا سيكون هناك شيء مثل
مضيف / بينغيتغير تسطير أسفل السطر باسم الطريقة إلى -. أي ستكون طريقة action_hello_world متاحة في
localhost / hello-worldسافرنا على.
كما هو الحال بالنسبة لتطبيقات واجهة المستخدم الرسومية ، سيكون من الجيد استخدام MVC (أو نمط آخر مع فصل المكون البصري والمنطق) ، وكذلك في الخدمة المجهرية. من الأفضل تحطيم الأشياء التي يمكن تحطيمها.
أي في حالتنا ، دع فئة الخدمة تستمر في أداء وظائف نفعية لتهيئة الخدمة وإطلاق المعالج المطلوب ، ووضع المنطق في فصل منفصل. للقيام بذلك ، نقوم بتعديل الرمز الخاص بنا كما يلي:
class TodoLogic extends ServiceBaseLogic { public function action_ping() { return ('I am alive!'); } } class TodoService extends ServiceBase { } Service::start('TodoService', 'TodoLogic');
ثم حصلنا على فصل مع المنطق:
class TodoLogic extends ServiceBaseLogic
موروثة من الفئة الأساسية ServiceBaseLogic (لها حد أدنى من الوظائف ، لذلك سنبحثها بالتفصيل لاحقًا).
توقفت فئة TodoService عن تنفيذ واجهة ServiceBaseLogicInterface (في الواقع ، لم تختف ، فقط تطبقها فئة ServiceBaseLogic الآن).
بعد إزالة المنطق ، اتضح أن فئة TodoService فارغة ويمكن فصلها بأمان ، مما يقلل الكود أكثر:
class TodoLogic extends ServiceBaseLogic { public function action_ping() { return ('I am alive!'); } } Service::start('ServiceBase', 'TodoLogic');
هنا ، فئة ServiceBase هي المسؤولة عن بدء الخدمة ، وليس عن الخدمة لدينا.
سافرنا إلى أبعد من ذلك.
في عملية استخدام إطار العمل الخاص بي ، في لحظة معينة ، بدأت الفصول الدراسية ذات المنطق الكبير الحجم تنفد. ما أغضب شعوري بالجمال من ناحية ، من ناحية أخرى ، كان سونار ساخطًا ، من ناحية ثالثة ، لم يكن مفهوم تقسيم الطرق إلى طرق القراءة وطرق الكتابة (انظر CQRS) واضحًا في كيفية تنفيذها.
لذلك ، في لحظة معينة ، أصبح من الممكن تجميع معالجات نقطة النهاية وفقًا لسمة واحدة أو أخرى وفقًا لفئات مختلفة من المنطق ، وإذا لزم الأمر ، فقم إما بتشغيلها داخل نفس الخدمة أو توزيعها دون مؤلم على أشكال مختلفة.
أي يمكنك إما القيام بكل منطق CRUD ضمن خدمة واحدة. ويمكن تقسيمها إلى خدمتين:
- واحد يوفر طرق القراءة ؛
- والآخر يوفر طرق تعديل البيانات.
لنقم الآن بإضافة طريقة إنشاء كيان وطريقة استرداد قائمة كيان إلى مثالنا:
class TodoSystemLogic extends ServiceBaseLogic { public function action_ping() { return ('I am alive!'); } } class TodoReadLogic extends ServiceBaseLogic { public function action_list() { return ('List!'); } } class TodoWriteLogic extends ServiceBaseLogic { public function action_create() { return ('Done!'); } } Service::start('ServiceBase', [ 'TodoSystemLogic', 'TodoReadLogic', 'TodoWriteLogic' ]);
سنتطرق فقط إلى التغييرات:
- فئات TodoSystemLogic (أساليب النظام) ، TodoReadLogic (قراءة الطرق) ، TodoWriteLogic (طرق الكتابة) ظهرت ؛
- عند بدء تشغيل الخدمة ، فإننا لا ننقل فئة واحدة مع المنطق ، ولكن عدة.
هذا كل شيء لهذا اليوم. سأناقش ميزات أخرى للإطار في المقالات التالية. هناك الكثير منهم. في غضون ذلك ، يمكنك أن ترى بنفسك
ما هو مثير للاهتمام هناك .