في عالم معماريات البرمجيات الحديثة، نادراً ما يكون النقاش بين REST و gRPC لعبة صفرية. بالنسبة لمعظم خدمات الميكروخدمات القائمة على الأحداث الجاهزة للإنتاج، تتضمن الاستراتيجية المثالية نهجاً هجيناً. من خلال الاستفادة من قابلية قراءة REST للبشر وشيوعها للعملاء الخارجيين، والكفاءة الثنائية لـ gRPC للتواصل الداخلي بين الخدمات، يمكن للمطورين تحقيق مكاسب كبيرة في معدل الإرسال وتقليل زمن الاستجابة.
الحجة لصالح البنية الهجينة
تتميز واجهات برمجة التطبيقات RESTful بأنها ممتازة لعدم الاعتماد على الحالة، وتوافق المتصفح، والتخزين المؤقت عبر معايير HTTP. ومع ذلك، فهي تعاني من عبء تسلسل JSON ونقص الدعم الأصلي للبث أو الاتصال ثنائي الاتجاه. على العكس من ذلك، يوفر gRPC، المبني على HTTP/2، تعدد الإرسال، والتحكم في التدفق، وعقوداً ذات أنواع قوية عبر Protocol Buffers. في نظام قائم على الأحداث عالي معدل الإرسال، تحتاج الخدمات الداخلية غالباً إلى التواصل بسرعة مع حمولات معقدة، مما يجعل gRPC الخيار الأفضل للحركة الداخلية. ومع ذلك، يفضل المستهلكون الخارجيون، وتطبيقات الجوال، والشركاء من الطرف الثالث غالباً بساطة REST.
تنفيذ النمط الهجين
جوهر هذه الاستراتيجية هو فصل طبقة النقل عن منطق الأعمال. يجب عليك تعريف واجهات خدمتك الأساسية باستخدام Protocol Buffers (ملفات .proto) لإ确立 مصدر حقيقة واحد. من هذا التعريف، يمكنك توليد stubs لـ gRPC للاستخدام الداخلي و handlers لـ REST للاستخدام الخارجي.
فكّر في "خدمة المستخدم" التي تعالج تحديثات ملفات تعريف المستخدم. داخلياً، تحتاج الخدمات الأخرى (مثل "خدمة الإشعارات") إلى الاشتراك في هذه التحديثات بكفاءة. خارجياً، يحتاج الواجهة الأمامية للويب إلى جلب ملفات تعريف المستخدم.
// user_service.proto
syntax = "proto3";
package users;
service UserProto {
rpc GetProfile (GetProfileRequest) returns (UserProfile) {}
rpc UpdateProfile (UpdateProfileRequest) returns (UserProfile) {}
rpc StreamProfileUpdates (StreamRequest) returns (stream UserProfile) {}
}
message UserProfile {
string id = 1;
string name = 2;
string email = 3;
}
استراتيجيات التوجيه والبوابة
لإدارة هذا التعايش، من الضروري وجود بوابة API أو نمط BFF (الخلفية للواجهة الأمامية). تعرض الخدمة الداخلية نقطة نهاية gRPC فقط. تستمع البوابة على المنفذ 8080 لطلبات REST/JSON وعلى المنفذ 50051 لطلبات gRPC. يتم تحويل طلبات REST الواردة إلى مكالمات gRPC داخلياً، مما يضمن بقاء منطق الأعمال الأساسي غير واعٍ بنمط الواجهة البرمجية الخارجية.
يسمح لك هذا النهج بـ: 1. تقليل زمن الاستجابة الداخلي: الترميز الثنائي لـ gRPC أصغر عادةً بنسبة 30-50% من JSON. 2. تمكين البث: استخدم بث خادم gRPC لنشر الأحداث في الوقت الفعلي بين خدمات الميكرو. 3. توحيد الواجهات البرمجية الخارجية: حافظ على REST لسهولة الاستخدام مع curl والمتصفحات والشركاء غير التقنيين.
تحسين معدل الإرسال باستخدام الأنماط القائمة على الأحداث
على الرغم من أن gRPC يعتمد على الطلب/الاستجابة، إلا أنه يتكامل بسلاسة مع المعماريات القائمة على الأحداث عند استخدامه عبر HTTP/2. من خلال الاستفادة من البث المدمج في gRPC، يمكنك إنشاء نقاط نهاية "بث الخادم" التي تعمل كمستهلكات أحداث خفيفة. بدلاً من استطلاع نقطة نهاية REST للحصول على أحداث جديدة، يمكن للخدمات الداخلية الحفاظ على بث gRPC دائم، وتلقي التحديثات في الوقت الفعلي بأقل قدر من العبء.
الخلاصة
اعتماد استراتيجية واجهة برمجة التطبيقات الهجينة لا يتطلب إعادة كتابة نظامك بأكمله. إنه يتطلب تحولاً في طريقة التفكير: انظر إلى REST و gRPC ليسا كمنافسين، بل كأدوات مكملة لطبقات مختلفة من بنيتك. من خلال عرض gRPC للمعالجة الداخلية للأحداث عالية الأداء و REST للوصول الخارجي، تبني نظاماً يكون ودياً للمطورين ومحسناً للأداء. مع نمو نطاقك، توفر هذه البنية المساحة اللازمة للتعامل مع الأحمال المتزايدة دون عنق الزجاجة المرتبط غالباً بمعماريات JSON الأحادية فقط.