gRPC مقابل REST: الشروع في العمل مع أفضل بروتوكول API
نشرت: 2022-07-22في المشهد التكنولوجي اليوم ، تتطلب معظم المشاريع استخدام واجهات برمجة التطبيقات. تعمل واجهات برمجة التطبيقات على ربط الاتصال بين الخدمات التي قد تمثل نظامًا واحدًا معقدًا ولكنها قد تكون موجودة أيضًا على أجهزة منفصلة أو تستخدم شبكات أو لغات متعددة وغير متوافقة.
تتناول العديد من التقنيات القياسية احتياجات الاتصال بين الخدمات للأنظمة الموزعة ، مثل REST أو SOAP أو GraphQL أو gRPC. في حين أن REST هو نهج مفضل ، فإن gRPC هي منافس جدير بتقديم أداء عالي وعقود مكتوبة وأدوات ممتازة.
نظرة عامة على REST
نقل الحالة التمثيلية (REST) هو وسيلة لاسترداد بيانات الخدمة أو معالجتها. يتم إنشاء REST API بشكل عام على بروتوكول HTTP ، باستخدام URI لتحديد مورد وفعل HTTP (على سبيل المثال ، GET ، PUT ، POST) لتحديد العملية المطلوبة. تحتوي هيئات الطلب والاستجابة على بيانات خاصة بالعملية ، بينما توفر رؤوسها البيانات الوصفية. للتوضيح ، دعنا نلقي نظرة على مثال مبسط لاسترداد منتج عبر واجهة برمجة تطبيقات REST.
هنا ، نطلب مورد منتج برقم 11
ونوجه واجهة برمجة التطبيقات للرد بتنسيق JSON:
GET /products/11 HTTP/1.1 Accept: application/json
بناءً على هذا الطلب ، قد يبدو ردنا (تم حذف العناوين غير ذات الصلة) كما يلي:
HTTP/1.1 200 OK Content-Type: application/json { id: 11, name: "Purple Bowtie", sku: "purbow", price: { amount: 100, currencyCode: "USD" } }
على الرغم من أن JSON قد يكون قابلاً للقراءة من قبل الإنسان ، إلا أنه ليس مثاليًا عند استخدامه بين الخدمات. يمكن أن تؤدي الطبيعة المتكررة للإشارة إلى أسماء الخصائص - حتى عند ضغطها - إلى تضخم الرسائل. دعونا نلقي نظرة على بديل لمعالجة هذا القلق.
نظرة عامة على gRPC
gRPC Remote Procedure Call (gRPC) هو بروتوكول اتصال مفتوح المصدر وقائم على عقد وعبر الأنظمة الأساسية يعمل على تبسيط وإدارة الاتصال بين الخدمات من خلال عرض مجموعة من الوظائف للعملاء الخارجيين.
بنيت على رأس HTTP / 2 ، gRPC تعزز ميزات مثل التدفق ثنائي الاتجاه وأمن طبقة النقل (TLS) المدمج. يتيح gRPC اتصالاً أكثر كفاءة من خلال الحمولات الثنائية المتسلسلة. يستخدم مخازن البروتوكول بشكل افتراضي كآليته لتسلسل البيانات المنظمة ، على غرار استخدام REST لـ JSON.
على عكس JSON ، فإن المخازن المؤقتة للبروتوكول هي أكثر من تنسيق متسلسل. وهي تشمل ثلاثة أجزاء رئيسية أخرى:
- لغة تعريف العقد موجودة في ملفات
.proto
(سنتبع proto3 ، أحدث مواصفات لغة المخزن المؤقت للبروتوكول.) - تم إنشاء رمز وظيفة الموصّل
- مكتبات وقت تشغيل خاصة بلغة معينة
يتم سرد الوظائف البعيدة المتوفرة في الخدمة (المعرفة في ملف .proto
) داخل عقدة الخدمة في ملف المخزن المؤقت للبروتوكول. كمطورين ، نحصل على هذه الوظائف ومعلماتها باستخدام نظام النوع الغني للمخازن المؤقتة للبروتوكول. يدعم هذا النظام مختلف أنواع الأرقام والتاريخ والقوائم والقواميس والأرقام الفارغة لتحديد رسائل الإدخال والإخراج.
يجب أن تكون تعريفات الخدمة هذه متاحة لكل من الخادم والعميل. لسوء الحظ ، لا توجد آلية افتراضية لمشاركة هذه التعريفات بخلاف توفير الوصول المباشر إلى ملف .proto
نفسه.
يعرّف ملف .proto
هذا المثال دالة لإرجاع إدخال منتج ، بمعرّف:
تجعل الكتابة الصارمة والترتيب الميداني لـ proto3 عملية إلغاء تسلسل الرسالة أقل ضرائب من تحليل JSON.
مقارنة REST مقابل gRPC
للتلخيص ، أهم النقاط عند مقارنة REST مقابل gRPC هي:
راحة | gRPC | |
---|---|---|
عبر منصة | نعم | نعم |
تنسيق الرسالة | مخصص ولكن بشكل عام JSON أو XML | مخازن البروتوكول |
حجم حمولة الرسالة | متوسط / كبير | صغير |
تعقيد المعالجة | أعلى (تحليل النص) | أقل (هيكل ثنائي واضح المعالم) |
دعم المتصفح | نعم (أصلي) | نعم (عبر gRPC-Web) |
حيث من المتوقع وجود عقود أقل صرامة وإضافات متكررة إلى الحمولة ، فإن JSON و REST مناسبان بشكل كبير. عندما تميل العقود إلى البقاء ثابتة وتكون السرعة ذات أهمية قصوى ، تفوز gRPC بشكل عام. في معظم المشاريع التي عملت عليها ، أثبت gRPC أنه أخف وزنًا وأكثر أداءً من REST.
تنفيذ خدمة gRPC
لنقم ببناء مشروع مبسط لاستكشاف مدى سهولة اعتماد gRPC.
إنشاء مشروع API
للبدء ، سننشئ مشروع .NET 6 في Visual Studio 2022 Community Edition (VS). سنقوم بتحديد قالب ASP.NET Core gRPC Service وتسمية المشروع (سنستخدم InventoryAPI
) والحل الأول ضمنه ( Inventory
) .
الآن ، دعنا نختار ملف. خيار NET 6.0 (دعم طويل الأجل) لإطار عملنا:
تحديد خدمة منتجاتنا
الآن بعد أن أنشأنا المشروع ، تعرض VS خدمة تعريف نموذج أولي لـ gRPC تسمى Greeter
. سنعيد استخدام ملفات Greeter
الأساسية لتناسب احتياجاتنا.
- لإنشاء العقد الخاص بنا ، سنقوم باستبدال محتويات
greet.proto
بـ Snippet 1 ، وإعادة تسمية الملفproduct.proto
. - لإنشاء خدمتنا ، سنقوم باستبدال محتويات ملف
GreeterService.cs
بـ Snippet 2 ، وإعادة تسمية الملفProductCatalogService.cs
.
ترجع الخدمة الآن منتجًا مشفرًا. لإنجاح الخدمة ، نحتاج فقط إلى تغيير تسجيل الخدمة في Program.cs
للإشارة إلى اسم الخدمة الجديد. في حالتنا ، سنعيد تسمية app.MapGrpcService<GreeterService>();
إلى app.MapGrpcService<ProductCatalogService>();
لجعل واجهة برمجة التطبيقات الجديدة الخاصة بنا قابلة للتشغيل.
تحذير عادل: ليس اختبار البروتوكول القياسي الخاص بك
في حين أننا قد نميل إلى تجربته ، لا يمكننا اختبار خدمة gRPC الخاصة بنا من خلال متصفح يستهدف نقطة النهاية الخاصة به. إذا حاولنا ذلك ، فسوف نتلقى رسالة خطأ تشير إلى أن الاتصال بنقاط نهاية gRPC يجب أن يتم من خلال عميل gRPC.
إنشاء العميل
لاختبار خدمتنا ، دعنا نستخدم نموذج تطبيق وحدة التحكم الأساسي الخاص بـ VS وإنشاء عميل gRPC لاستدعاء API. قمت بتسمية تطبيق InventoryApp
بي.
من أجل النفعية ، دعنا نشير إلى مسار ملف نسبي سنشارك من خلاله عقدنا. سنضيف المرجع يدويًا إلى ملف .csproj
. بعد ذلك ، سنقوم بتحديث المسار وتعيين وضع Client
. ملاحظة: أوصيك بالتعرف على بنية المجلد المحلي لديك وثقة في هيكلها قبل استخدام المراجع النسبية.
فيما يلي مراجع .proto
، كما تظهر في ملفات مشروع العميل والخدمة:
ملف مشروع الخدمة (رمز لنسخه إلى ملف مشروع العميل) | ملف مشروع العميل (بعد اللصق والتحرير) |
---|---|
|
|
الآن ، للاتصال بخدمتنا ، سنقوم باستبدال محتويات Program.cs
. سيحقق الكود الخاص بنا عددًا من الأهداف:
- قم بإنشاء قناة تمثل موقع نقطة نهاية الخدمة (قد يختلف المنفذ ، لذا راجع ملف
launchsettings.json
لمعرفة القيمة الفعلية). - قم بإنشاء كائن العميل.
- أنشئ طلبًا بسيطًا.
- أرسل الطلب.
التحضير للإطلاق
لاختبار الكود الخاص بنا ، في VS ، سننقر بزر الماوس الأيمن فوق الحل ونختار Set Startup Projects . في مربع حوار صفحات خصائص الحل ، سنقوم بما يلي:
- حدد زر الاختيار بجوار مشاريع بدء التشغيل المتعددة ، وفي القائمة المنسدلة الإجراء ، اضبط كلا المشروعين (
InventoryAPI
وInventoryApp
) على البدء . - انقر فوق "موافق" .
يمكننا الآن بدء الحل بالنقر فوق " ابدأ " في شريط أدوات VS (أو بالضغط على مفتاح F5 ). سيتم عرض نافذتين جديدتين لوحدة التحكم: واحدة تخبرنا أن الخدمة تستمع ، والأخرى لتظهر لنا تفاصيل المنتج المسترجع.
مشاركة عقد gRPC
لنستخدم الآن طريقة أخرى لتوصيل عميل gRPC بتعريف خدمتنا. إن أكثر حلول مشاركة العقود التي يمكن الوصول إليها من قبل العميل هو إتاحة تعريفاتنا من خلال عنوان URL. الخيارات الأخرى إما هشة للغاية (ملف مشترك من خلال مسار) أو تتطلب المزيد من الجهد (عقد مشترك من خلال حزمة أصلية). المشاركة من خلال عنوان URL (كما يفعل SOAP و Swagger / OpenAPI) تتسم بالمرونة وتتطلب رمزًا أقل.
للبدء ، اجعل ملف .proto
متاحًا كمحتوى ثابت. سنقوم بتحديث الكود الخاص بنا يدويًا لأن واجهة المستخدم في إجراء الإنشاء مضبوطة على "Protobuf Compiler". يوجه هذا التغيير المترجم لنسخ ملف .proto
بحيث يمكن تقديمه من عنوان ويب. إذا تم تغيير هذا الإعداد من خلال VS UI ، فسيتعطل الإصدار. خطوتنا الأولى إذن هي إضافة Snippet 4 إلى ملف InventoryAPI.csproj
:
بعد ذلك ، نقوم بإدخال الكود في Snippet 5 أعلى ملف ProductCatalogService.cs
لإعداد نقطة نهاية لإرجاع ملف .proto
بنا:
والآن ، نضيف Snippet 6 قبل app.Run()
، أيضًا في ملف ProductCatalogService.cs
:
مع إضافة Snippets 4-6 ، يجب أن تكون محتويات ملف .proto
مرئية في المتصفح.
عميل اختبار جديد
نريد الآن إنشاء عميل وحدة تحكم جديد سنقوم بتوصيله بخادمنا الحالي باستخدام معالج تبعية VS. المشكلة هي أن هذا المعالج لا يتحدث عن HTTP / 2. لذلك ، نحتاج إلى ضبط خادمنا للتحدث عبر HTTP / 1 وبدء الخادم. مع إتاحة خادمنا الآن لملف .proto
، يمكننا بناء عميل اختبار جديد يتم ربطه بخادمنا عبر معالج gRPC.
- لتغيير خادمنا للتحدث عبر HTTP / 1 ، سنقوم بتحرير ملف
appsettings.json
JSON الخاص بنا:- اضبط حقل
Protocol
(الموجود في مسارKestrel.EndpointDefaults.Protocols
) لقراءةHttps
. - حفظ الملف.
- اضبط حقل
- لكي يقرأ عميلنا الجديد هذه المعلومات
proto
، يجب أن يكون الخادم قيد التشغيل. في الأصل ، بدأنا كلاً من العميل السابق وخادمنا من مربع حوار Set Startup Projects في VS. اضبط حل الخادم لبدء مشروع الخادم فقط ، ثم ابدأ الحل. (الآن بعد أن قمنا بتعديل إصدار HTTP ، لم يعد بإمكان عميلنا القديم الاتصال بالخادم.) - بعد ذلك ، قم بإنشاء عميل الاختبار الجديد. قم بتشغيل مثيل آخر من VS. سنكرر الخطوات كما هو مفصل في قسم إنشاء مشروع واجهة برمجة التطبيقات ، ولكن هذه المرة ، سنختار نموذج تطبيق وحدة التحكم . سنقوم بتسمية مشروعنا والحل
InventoryAppConnected
. - مع إنشاء هيكل العميل ، سنتصل بخادم gRPC الخاص بنا. قم بتوسيع المشروع الجديد في VS Solution Explorer.
- انقر بزر الماوس الأيمن فوق التبعيات ، وفي قائمة السياق ، حدد إدارة الخدمات المتصلة .
- في علامة التبويب "الخدمات المتصلة" ، انقر فوق إضافة مرجع خدمة واختر gRPC .
- في مربع الحوار Add Service Reference ، حدد خيار URL وأدخل إصدار
http
من عنوان الخدمة (تذكر الحصول على رقم المنفذ الذي تم إنشاؤه عشوائيًا منlaunchsettings.json
) . - انقر فوق " إنهاء " لإضافة مرجع خدمة يمكن صيانته بسهولة.
لا تتردد في التحقق من عملك مقابل نموذج التعليمات البرمجية لهذا المثال. نظرًا لأن VS قد أنشأت ، تحت الغطاء ، نفس العميل الذي استخدمناه في الجولة الأولى من الاختبار ، يمكننا إعادة استخدام محتويات ملف Program.cs
من الخدمة السابقة حرفياً.
عندما نغير عقدًا ، نحتاج إلى تعديل تعريف gRPC الخاص بالعميل لمطابقة تعريف .proto
المحدث. للقيام بذلك ، نحتاج فقط إلى الوصول إلى الخدمات المتصلة الخاصة بـ VS وتحديث إدخال الخدمة ذات الصلة. الآن ، اكتمل مشروع gRPC الخاص بنا ، ومن السهل الحفاظ على تزامن خدمتنا وعميلنا.
المرشح التالي لمشروعك: gRPC
يوفر تطبيق gRPC الخاص بنا لمحة مباشرة عن فوائد استخدام gRPC. لكل من REST و gRPC حالات الاستخدام المثالية الخاصة بهم اعتمادًا على نوع العقد. ومع ذلك ، عندما يكون كلا الخيارين مناسبين ، فإنني أشجعك على تجربة gRPC - فهي ستضعك في مقدمة المنحنى في مستقبل واجهات برمجة التطبيقات.