gRPC لـ TypeScript: المكتبات، الإعداد وأمثلة الكود

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

gRPC لـ TypeScript: المكتبات والأمثلة



gRPC هو إطار عمل حديث عالي الأداء لاستدعاء الإجراءات عن بُعد (RPC)، تم تطويره بواسطة Google. يستخدم Protocol Buffers (protobuf) كلغة لتعريف الواجهات وتنسيق تسلسل البيانات. في TypeScript، يتم تنفيذ gRPC من خلال الحزم @grpc/grpc-js (لمنطق الخادم والعميل) و protobufjs (للعمل مع ملفات .proto). في هذه المقالة، سنشرح المكتبات الرئيسية، إعداد البيئة، وسنكتب مثالاً عملياً باستخدام TypeScript.



المكتبات الرئيسية لـ gRPC في TypeScript



  • @grpc/grpc-js — تنفيذ خالص لـ gRPC بلغة JavaScript (بدون إضافات C++). يدعم جميع الوظائف الأساسية: الاستدعاءات الأحادية، التدفق من الخادم والعميل، والتدفق ثنائي الاتجاه.
  • protobufjs — مكتبة لتحميل وتحليل وتوليد الفئات من ملفات .proto. تسمح بإنشاء الرسائل والخدمات ديناميكياً.
  • @grpc/proto-loader — حزمة مساعدة تبسط تحميل ملفات proto وتقوم تلقائياً بتوليد أنواع TypeScript بناءً على التعريفات.
  • ts-protoc-gen — مولد كود للمترجم protoc. يسمح بتوليد فئات وواجهات مطبّقة بشدة من ملفات .proto.


معظم المشاريع تكفيها مجموعة @grpc/grpc-js + @grpc/proto-loader. إذا كانت هناك حاجة لأقصى درجات أمان الأنواع، يتم استخدام ts-protoc-gen أو protobufjs مع توليد أنواع ثابتة.



تثبيت التبعيات



أنشئ مشروعاً جديداً وقم بتثبيت الحزم اللازمة:



mkdir grpc-typescript-examplecd grpc-typescript-examplenpm init -ynpm install @grpc/grpc-js @grpc/proto-loadernpm install -D typescript @types/nodenpx tsc --init


إنشاء ملف proto



لنقم بتعريف خدمة بسيطة للتعامل مع المستخدمين. أنشئ ملفاً باسم user.proto:



syntax = "proto3";

package user;

service UserService { rpc GetUser (GetUserRequest) returns (User); rpc ListUsers (ListUsersRequest) returns (stream User);}

message GetUserRequest { int32 id = 1;}

message ListUsersRequest { int32 page = 1; int32 limit = 2;}

message User { int32 id = 1; string name = 2; string email = 3;}


تنفيذ خادم gRPC باستخدام TypeScript



لنقم بإنشاء ملف server.ts:



import * as grpc from '@grpc/grpc-js';import * as protoLoader from '@grpc/proto-loader';import path from 'path';

const PROTO_PATH = path.join(__dirname, 'user.proto');

const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true,});

const userProto = grpc.loadPackageDefinition(packageDefinition) as any;

// محاكاة قاعدة بياناتconst users = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' },];

function getUser( call: grpc.ServerUnaryCall<{ id: number }, any>, callback: grpc.sendUnaryData<any>) { const user = users.find(u => u.id === call.request.id); if (!user) { return callback({ code: grpc.status.NOT_FOUND, message: 'User not found', }); } callback(null, user);}

function listUsers(call: grpc.ServerWritableStream<{ page: number; limit: number }, any>) { const page = call.request.page || 1; const limit = call.request.limit || 10; const start = (page - 1) * limit; const end = start + limit; const paginatedUsers = users.slice(start, end); paginatedUsers.forEach(user => call.write(user)); call.end();}

function main() { const server = new grpc.Server();

توصيات