إذا كنت قد حاولت استدعاء خدمة gRPC من المتصفح، فأنت تعرف المشكلة: المتصفح لا يستطيع التحدث بـ gRPC الخام لأنه لا يتيح التحكم الكامل في تذييلات HTTP. النتيجة المعتادة هي إضافة وكيل مثل Envoy لترجمة الحركة. ConnectRPC يختصر هذا المسار: تعرّف API باستخدام Protobuf، وتبني خادمًا يمكن للمتصفح استدعاؤه مباشرة، ويمكن اختباره بـ curl، ويظل متوافقًا مع منظومة gRPC.
في هذا الدليل سنركّز على الجانب العملي: ما الذي يقدمه ConnectRPC، متى تستخدمه بدل gRPC أو gRPC-Web أو REST، كيف يبدو طلب Connect عبر HTTP، وكيف تختبر نقاط النهاية باستخدام أدوات HTTP و gRPC عادية.
ما هو ConnectRPC
ConnectRPC هي مجموعة مكتبات لبناء واجهات API مبنية على Protocol Buffers، لكنها قابلة للاستخدام مباشرة من المتصفح ومتوافقة مع gRPC.
سير العمل الأساسي:
- تكتب العقد في ملف
.proto. - تولّد الرسائل والعملاء والمعالجات.
- تنفّذ منطق الخدمة.
- تسجّل المعالجات على خادم HTTP.
مثال مبسط لتعريف خدمة:
syntax = "proto3";
package greet.v1;
service GreetService {
rpc Greet(GreetRequest) returns (GreetResponse);
}
message GreetRequest {
string name = 1;
}
message GreetResponse {
string greeting = 1;
}
تم إنشاء المشروع بواسطة Buf، الشركة التي تطوّر أدوات buf الخاصة بـ Protobuf، وهو الآن مشروع sandbox ضمن CNCF. لذلك يتناسب Connect مع أسلوب schema-first المستخدم عادة مع Protobuf و buf.
خادم ConnectRPC يستطيع دعم ثلاثة بروتوكولات في نفس الوقت:
- gRPC: توافق مع عملاء gRPC، بما في ذلك التدفق والتذييلات.
- gRPC-Web: دعم مباشر للمتصفح بدون وكيل منفصل في كثير من الحالات.
- Connect: بروتوكول HTTP أبسط ومناسب للويب.
هذا يعني أن نفس الخادم يمكن أن يخدم:
- عميل gRPC داخلي.
- تطبيق ويب يستخدم Connect.
- أداة HTTP مثل
curl. - عميل gRPC-Web عند الحاجة.
المشكلة التي يحلها Connect
gRPC قوي وسريع، لكنه يفترض بيئة لا تناسب المتصفح دائمًا:
- يعتمد على HTTP/2.
- يستخدم تذييلات HTTP لحمل حالة gRPC.
- يحتاج إلى تأطير ثنائي خاص.
- يصعب اختباره بأدوات HTTP عادية.
المتصفحات لا تعطي JavaScript تحكمًا كافيًا في التذييلات، لذلك لا يمكنها العمل كعميل gRPC أصلي. الحل التقليدي هو:
Browser -> gRPC-Web -> Envoy -> gRPC Backend
هذا يعمل، لكنه يضيف طبقة تشغيلية جديدة:
- إعداد وكيل.
- إدارة إعدادات CORS والبروتوكولات.
- تصحيح أخطاء في قفزة إضافية.
- مزيد من التعقيد في بيئة التطوير و CI.
Connect يقدّم مسارًا أبسط:
Browser -> Connect over HTTP -> Connect Server
وفي نفس الوقت يمكن للخادم نفسه استقبال gRPC:
gRPC Client -> gRPC -> Connect Server
النتيجة: واجهة خلفية واحدة يمكن استدعاؤها من المتصفح، ومن خدمات gRPC، ومن أدوات HTTP.
Connect مقابل gRPC مقابل gRPC-Web مقابل REST
هذه الخيارات ليست بدائل متطابقة. لكل واحد منها نقطة قوة.
gRPC
يستخدم gRPC Protobuf عبر HTTP/2 مع تأطير ثنائي وتذييلات. مناسب جدًا للاتصال بين الخدمات الداخلية، ويدعم جميع أنماط التدفق الأربعة.
لكن من المتصفح أو من shell يكون أقل راحة. إذا أردت فهم طبقة النقل، راجع كيف يعمل gRPC و HTTP/2 معًا.
gRPC-Web
gRPC-Web يقرّب gRPC من المتصفح، لكنه غالبًا يحتاج إلى وكيل يترجم بين gRPC-Web و gRPC الأصلي. لمعرفة متى يكون مناسبًا، راجع ما هو gRPC-Web.
Connect
Connect يحتفظ بمزايا Protobuf ونموذج الخدمات المشابه لـ gRPC، لكنه يجعل الاستدعاءات الأحادية تبدو كطلبات HTTP عادية:
-
POSTعادي. - جسم JSON أو Protobuf.
- رموز حالة HTTP حقيقية.
- لا حاجة إلى تأطير gRPC في طلبات Unary.
- قابل للاستخدام عبر HTTP/1.1 و HTTP/2 و HTTP/3.
REST
REST واسع الانتشار وسهل الاستدعاء، لكنه لا يفرض مخططًا قويًا ولا يعطيك توليد كود بنفس مستوى Protobuf. إذا كنت تقارن بين النمطين، راجع gRPC مقابل REST.
الخلاصة العملية:
- استخدم gRPC عندما يكون الاتصال بين خدمات داخلية وتحتاج إلى كفاءة وتدفق.
- استخدم gRPC-Web عندما لديك gRPC قائم وتريد دعمه من المتصفح.
- استخدم REST عندما تريد واجهة موارد تقليدية ومتوافقة عالميًا.
- استخدم Connect عندما تريد Protobuf وكتابة قوية، لكن مع تجربة HTTP سهلة للمتصفح والأدوات.
يعتمد Connect على نموذج Protobuf وطريقة gRPC، لكنه يتجنب الأجزاء التي تجعل gRPC الخام صعبًا في المتصفحات والـ shells.
طلب Connect عبر HTTP
استدعاء Connect الأحادي هو طلب HTTP POST.
تنسيق المسار:
/<package>.<Service>/<Method>
إذا كان لديك:
package greet.v1;
service GreetService {
rpc Greet(GreetRequest) returns (GreetResponse);
}
فالمسار يكون:
/greet.v1.GreetService/Greet
يمكنك استدعاؤه بـ curl:
curl \
--header "Content-Type: application/json" \
--data '{"name": "Jane"}' \
http://localhost:8080/greet.v1.GreetService/Greet
الاستجابة:
{"greeting": "Hello, Jane!"}
لا تحتاج إلى عميل خاص، ولا وكيل، ولا فك ترميز ثنائي أثناء التطوير.
اختيار نوع المحتوى
يدعم Connect في طلبات Unary نوعين رئيسيين:
-
application/json: مناسب للتطوير والتصحيح لأنه قابل للقراءة. -
application/proto: مناسب عندما تريد حجمًا أصغر على الشبكة.
مثال باستخدام JSON:
curl \
--header "Content-Type: application/json" \
--data '{"name": "Jane"}' \
http://localhost:8080/greet.v1.GreetService/Greet
مثال باستخدام Protobuf ثنائي:
curl \
--header "Content-Type: application/proto" \
--data-binary @request.bin \
http://localhost:8080/greet.v1.GreetService/Greet
طلبات التدفق تستخدم أنواع محتوى مختلفة مثل:
application/connect+proto
application/connect+json
وتغلف كل رسالة داخل envelope يتكون من:
- بايت إشارة واحد.
- طول الرسالة بأربعة بايتات big-endian.
- الرسالة نفسها.
أما طلبات Unary فلا تستخدم هذا الغلاف، لذلك يمكن التعامل معها كطلبات HTTP عادية. إذا كنت تختار بين JSON و Protobuf، راجع Protobuf مقابل JSON.
توليد الكود باستخدام buf
يدعم ConnectRPC عدة لغات. Go و TypeScript للمتصفح و Node.js مستقران وجاهزان للإنتاج. Swift متاح لمنصات Apple، و Kotlin لـ JVM و Android، و Python في مرحلة تجريبية.
الفكرة العملية: تكتب ملف .proto مرة واحدة، ثم تولّد منه كود الخادم والعملاء.
في مشروع Go مثلًا تحتاج عادة إلى:
-
protoc-gen-goلتوليد رسائل Protobuf. -
protoc-gen-connect-goلتوليد كود Connect.
مثال buf.gen.yaml مبسط:
version: v2
plugins:
- remote: buf.build/protocolbuffers/go
out: gen
opt: paths=source_relative
- remote: buf.build/connectrpc/go
out: gen
opt: paths=source_relative
ثم شغّل:
buf generate
بعد التوليد تحصل على:
- أنواع رسائل قوية.
- واجهات الخدمة.
- كود تسجيل المعالجات.
- عملاء يمكن استخدامها من الكود.
في Go، معالجات Connect تعمل فوق net/http، لذلك يمكنك تركيبها بجانب مسارات HTTP الحالية بدل تشغيل runtime منفصل.
مثال شكل التسجيل يكون عادة قريبًا من هذا النمط:
mux := http.NewServeMux()
path, handler := greetv1connect.NewGreetServiceHandler(&GreetServer{})
mux.Handle(path, handler)
http.ListenAndServe(":8080", mux)
اختبار وتصحيح أخطاء نقاط نهاية Connect و gRPC
بما أن استدعاءات Connect الأحادية هي HTTP عادي، يمكنك اختبارها بنفس أسلوب اختبار REST.
الاختبار باستخدام curl
curl \
--request POST \
--header "Content-Type: application/json" \
--data '{"name": "Jane"}' \
http://localhost:8080/greet.v1.GreetService/Greet
تحقق من:
- رمز حالة HTTP.
- جسم الاستجابة.
- الرؤوس.
- رسالة الخطأ عند فشل الطلب.
الاختبار باستخدام Apidog
في Apidog، أرسل طلب Connect الأحادي كطلب HTTP عادي:
- اختر method:
POST. - استخدم URL مثل:
http://localhost:8080/greet.v1.GreetService/Greet
- أضف الرأس:
Content-Type: application/json
- ضع الجسم:
{"name": "Jane"}
- نفّذ الطلب وتحقق من الاستجابة.
Apidog ليس بحاجة إلى دعم خاص لبروتوكول Connect في هذا السيناريو، لأنك تختبر الواجهة HTTP التي يكشفها Connect. إذا أردت مراجعة أساسيات أفعال HTTP، راجع ما هي طرق HTTP.
اختبار جانب gRPC من نفس الخادم
لأن خادم Connect يستطيع التحدث بـ gRPC أيضًا، يمكنك اختبار جانب gRPC من نفس الخدمة.
في Apidog يمكنك:
- استيراد ملف
.proto. - تصفح الخدمات والطرق.
- إنشاء طلب gRPC مكتوب.
- تنفيذ الطلب ومراجعة الاستجابة.
بهذا تحصل على أداة واحدة لاختبار:
- واجهة Connect الصديقة لـ HTTP.
- واجهة gRPC الأصلية.
إذا كان تركيزك على gRPC، راجع كيفية اختبار واجهات برمجة تطبيقات gRPC بكفاءة.
تشغيل الاختبارات في CI
بعد حفظ طلبات Connect و gRPC كسيناريوهات اختبار، يمكنك تشغيلها آليًا باستخدام Apidog CLI.
ثبّت الأداة:
npm install -g apidog-cli
ثم شغّل سيناريو أو مجموعة محفوظة:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
هذا مناسب لخطوات CI لأنه يعمل بلا واجهة رسومية، ويشغّل السيناريوهات المحفوظة بدل إرسال طلبات عشوائية. استخدمه لفحوصات التراجع على نقاط نهاية Connect و gRPC.
لشرح كامل، راجع البرنامج التعليمي لـ Apidog CLI لاختبار واجهة برمجة تطبيقات من سطر الأوامر.
الأسئلة الشائعة
هل ConnectRPC هو نفسه gRPC؟
لا. ConnectRPC هو إطار عمل يدعم ثلاثة بروتوكولات: gRPC و gRPC-Web وبروتوكول Connect. خادم Connect يمكنه التفاعل مع عملاء gRPC، لكن بروتوكول Connect نفسه تصميم HTTP منفصل يمكن للمتصفحات وأدوات shell استدعاؤه مباشرة.
هل أحتاج إلى Envoy للوصول من المتصفح؟
ليس عند استخدام بروتوكول Connect. يمكن للمتصفح استدعاء خادم Connect عبر HTTP القياسي. تحتاج إلى وكيل مثل Envoy فقط إذا كان لديك خادم خلفي يتحدث gRPC الأصلي فقط وتريد ربط المتصفح به.
ما اللغات التي يدعمها ConnectRPC؟
Go و TypeScript للمتصفح و Node.js هي التطبيقات المستقرة والجاهزة للإنتاج. Swift و Kotlin و Python متاحة أيضًا، مع Python في مرحلة تجريبية. جميعها تعتمد على نفس مخطط Protobuf.
ما علاقة Connect بـ buf؟
تم إنشاء ConnectRPC بواسطة Buf، ويستخدم عادة أدوات buf لتوليد الكود. يمكنك تشغيل:
buf generate
مع إضافات مثل protoc-gen-connect-go لإنتاج المعالجات والعملاء من ملفات .proto.
هل يمكنني اختبار نقطة نهاية Connect باستخدام عميل API عادي؟
نعم. استدعاءات Connect الأحادية هي طلبات HTTP POST بجسم JSON أو Protobuf ورمز حالة HTTP حقيقي. يمكن لأي عميل HTTP مثل curl أو Apidog إرسالها. ويمكن لـ Apidog أيضًا اختبار جانب gRPC من نفس الخادم عبر استيراد ملف .proto.
Top comments (0)