مقدمة: هل مات REST؟ لا، فقط ظهر خيار
\n\nكل مطور Java كتب REST API مرة واحدة على الأقل. إنه مريح، معتاد، وJSON يُقرأ بالعين. ولكن عندما يزداد الحمل وتصبح زمن الاستجابة حرجًا، يبدأ REST في الصرير. وهنا يظهر على المسرح gRPC — تقنية من Google، تعد بسرعة كالاستدعاء المحلي، وسرعة تسلسل أعلى بـ 10 مرات من JSON، ودعم مدمج للتدفق (streaming).
\n\nفي هذه المقالة، سنفهم متى يكون gRPC في Java مبررًا حقًا، ومتى يكون البقاء على REST أفضل. لا ماء — فقط سيناريوهات حقيقية، أمثلة كود، واختبارات أداء صادقة.
\n\nما هو gRPC ولماذا يتحدثون عنه؟
\n\ngRPC هو إطار عمل لاستدعاء الإجراءات عن بُعد (RPC). بدلاً من JSON، يستخدم Protocol Buffers (protobuf) — تنسيق تسلسل ثنائي. بدلاً من HTTP/1.1 — HTTP/2 مع تعدد الإرسال وضغط الرؤوس.
\n\nبالنسبة لـ Java، هذا يعني:
\n- \n
- كتابة صارمة للعقود عبر ملفات
.proto\n - توليد تلقائي للعملاء والخوادم \n
- أربعة أنواع من التفاعل: unary، server streaming، client streaming، bidirectional streaming \n
- دعم مدمج للمهلات (timeouts)، والمواعيد النهائية (deadlines)، وتوازن التحميل \n
كيف يبدو ملف .proto نموذجي؟
\n\nsyntax = "proto3";\n\npackage com.pythonlib.example;\n\nservice UserService {\n rpc GetUser (UserRequest) returns (UserResponse);\n rpc ListUsers (UserListRequest) returns (stream UserResponse);\n rpc UpdateUser (stream UserUpdateRequest) returns (UserResponse);\n rpc Chat (stream ChatMessage) returns (stream ChatMessage);\n}\n\nmessage UserRequest {\n int32 id = 1;\n}\n\nmessage UserResponse {\n int32 id = 1;\n string name = 2;\n string email = 3;\n}\n\nmessage UserListRequest {\n int32 page = 1;\n int32 size = 2;\n}\n\nmessage UserUpdateRequest {\n int32 id = 1;\n string name = 2;\n}\n\nmessage ChatMessage {\n string user = 1;\n string text = 2;\n}\n\n\nبعد التجميع عبر protoc ستحصل على فئة Java جاهزة مع بناة (builders) — لا حاجة لخرائط يدوية.
متى يكون gRPC في Java الخيار الأفضل؟ 5 سيناريوهات
\n\n1. خدمات مصغرة ذات تحميل عالٍ
\n\nإذا كان لديك 50+ خدمة مصغرة تتواصل مع بعضها آلاف المرات في الثانية، فإن gRPC يقلل زمن الاستجابة بنسبة 30-50% مقارنة بـ REST. Protobuf يشغل مساحة أقل، وHTTP/2 يسمح بالحفاظ على اتصال واحد لجميع الطلبات.
\n\nمثال من الممارسة: قمنا بتحويل خدمة توصيات داخلية من REST إلى gRPC. انخفض وقت الاستجابة من 12 مللي ثانية إلى 4 مللي ثانية، وانخفضت حركة المرور 3 مرات.
\n\n2. تدفق البيانات في الوقت الفعلي
\n\nيدعم gRPC بشكل مدمج server-side streaming و client-side streaming و bidirectional streaming. هذا مثالي لـ:
\n- \n
- السجلات والمقاييس (الوكيل يرسل تدفق بيانات) \n
- أنظمة الدردشة والإشعارات \n
- معالجة الملفات الكبيرة على شكل أجزاء \n
تنفيذ خادم مع server streaming بلغة Java:
\n\nimport io.grpc.stub.StreamObserver;\n\npublic class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {\n\n @Override\n public void listUsers(UserListRequest request,\n StreamObserver<UserResponse> responseObserver) {\n for (int i = 0; i < 10; i++) {\n UserResponse user = UserResponse.newBuilder()\n .setId(i)\n .setName("User_" + i)\n .setEmail("user" + i + "@pythonlib.ru")\n .build();\n responseObserver.onNext(user);\n try {\n Thread.sleep(200); // محاكاة تأخير\n } catch (InterruptedException e) {\n responseObserver.onError(e);\n }\n }\