لنبدأ بفهم المشكلة: تريد تعريف حقل inputVar
في الهيكل Request
كمتغير من نوع map[string]interface{}
بدلاً من map[string]string
. هذا يتطلب بعض التعديلات في التعريفات. لكن للأسف، لا يمكنك تعريف نفس النوع map[string]interface{}
مباشرة في ملف بروتوكول gRPC. بدلاً من ذلك، يجب عليك استخدام الأنواع المدعومة في gRPC.
بما أن gRPC لا يدعم نوع map
مباشرة، يمكنك استخدام الأنواع المدعومة مثل repeated
لإنشاء هيكل يتضمن البيانات التي تريد تخزينها بشكل ديناميكي.
إليك كيف يمكنك تحقيق ذلك:
protobufsyntax = "proto3"; package Trail; import "google/protobuf/any.proto"; service TrailFunc { rpc HelloWorld (Request) returns (Reply) {} } // The request message containing the user's name. message Request { repeated KeyValue inputVar = 1; } // Key value pair message message KeyValue { string key = 1; google.protobuf.Any value = 2; } // The response message containing the greetings message Reply { string outputVar = 1; }
في هذا التعريف الجديد، استخدمنا repeated
بدلاً من map
لتعريف حقل inputVar
. وبدلاً من تخزين القيمة كنوع string
، قمنا بتعريف هيكل KeyValue
يتكون من مفتاح key
من النوع string
وقيمة value
من النوع google.protobuf.Any
، وهذا يتيح لك تخزين أي نوع من البيانات بما في ذلك map[string]interface{}
.
المزيد من المعلومات
بالطبع، هذا هو التعريف الجديد للملف البروتوكولي. والآن دعنا ننتقل إلى كيفية استخدام هذا التعريف في تطبيقك في جافا.
أولاً، يجب عليك توليد ملفات Golang من الملف البروتوكولي الجديد باستخدام أداة protoc. يمكنك القيام بذلك باستخدام الأمر التالي:
bashprotoc --go_out=. --go-grpc_out=. your_protobuf_file.proto
ثم يمكنك استيراد المكتبة في تطبيقك في جافا واستخدامها كما يلي:
gopackage main
import (
"context"
"fmt"
"google.golang.org/grpc"
pb "your_protobuf_package" // استبدلها بالحزمة الخاصة بك
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
fmt.Printf("could not connect: %v", err)
}
defer conn.Close()
client := pb.NewTrailFuncClient(conn)
// إنشاء بند طلب جديد
request := &pb.Request{
InputVar: []*pb.KeyValue{
{Key: "key1", Value: &pb.Any{Value: []byte("value1")}},
{Key: "key2", Value: &pb.Any{Value: []byte("value2")}},
},
}
// استدعاء RPC
reply, err := client.HelloWorld(context.Background(), request)
if err != nil {
fmt.Printf("error from server: %v", err)
}
fmt.Printf("Response from server: %s\n", reply.OutputVar)
}
هذا كل ما عليك فعله لاستخدام تعريف البروتوكول الجديد في تطبيقك. يمكنك الآن بناء تطبيق gRPC في جافا يتيح للعميل تمرير البيانات كـ map[string]interface{}
كمتغير inputVar
في طلبه.
يجب أن تتحقق من تحديث الأنواع وفقًا للتعريف الجديد في كل من العميل والخادم. ويمكنك بعد ذلك تجربة التطبيق للتأكد من أن كل شيء يعمل كما هو متوقع.