Maison > Article > développement back-end > GO et GRPC : Création de classes protobuff "à la volée"
Je suis nouveau sur GRPC et je n'arrive pas à résoudre un problème. Est-il possible de créer un fichier protobuff lorsque l'application est déjà en cours d'exécution ?
Par exemple, je reçois un json
de l'utilisateur comme ceci :
"protobuf_file": "protobuf.proto", // File will be also recieved from user "service_name": "Unary", "method_name": "GetServerResponse", "request_data_serializer_name": "MessageRequest", "body": "grpc_request_data.json", // File will be also recieved from user
Ici, j'ai un .proto
fichier, un nom de service, une méthode et un message, et un autre json avec des données pour remplir le message.
Je dois maintenant ouvrir la connexion et appeler la méthode requise avec les données fournies.
TY!
PS .proto
Le fichier (extrait du Guide d'instructions d'obtention) sera :
syntax = "proto3"; package protobuf_all_modes; service Unary { rpc GetServerResponse(MessageRequest) returns (MessageResponse) {} } message MessageRequest { string message = 1; } message MessageResponse { string message = 1; int32 random_int32 = 2; }
Le deuxième json
sera :
{ "message": "hello World!" }
Je ne sais pas où chercher une solution. Toutes les suggestions seraient grandement appréciées
Si quelqu'un a le même problème, il existe une très bonne bibliothèque - https://pkg.go.dev/github.com/jhump/[ email protégé] /dynamic et un sous-packagehttps://pkg.go.dev/github. com/jhump/[email protégé]/dynamic/grpcdynamic
L'extrait de code serait :
parser
func NewGrpcObject(operation *BaseOperation) *GrpcObject { fns, err := protoparse.ResolveFilenames([]string{"./"}, operation.ProtoFile) // prase .proto file if err != nil { log.Error(err) } parser := protoparse.Parser{} fds, err := parser.ParseFiles(fns...) if err != nil { log.Error(err) } descriptor := fds[0] // In my case there will be only one .proto pkg := descriptor.GetPackage() serviceDescriptor := descriptor.FindService(pkg + "." + operation.ServiceName) // name of service descriptor will be with package name first methodDescriptor := serviceDescriptor.FindMethodByName(operation.MethodName) requestDescriptor := methodDescriptor.GetInputType() // You can get types for request and response responseDescriptor := methodDescriptor.GetOutputType() return &GrpcObject{ RequestDesc: requestDescriptor, MethodDesc: methodDescriptor, ResponseDesc: responseDescriptor, } }
caller
// connect conn, _ := grpc.Dial(operation.Host, grpc.WithTransportCredentials(credentials.NewTLS(c.TLSClientConfig.NewTLSConfig()))) stub = grpcdynamic.NewStub(conn) // call message := dynamic.NewMessage(operation.GrpcObject.RequestDesc) // from parser message.UnmarshalJSON(operation.Body) // here a JSON to fill message resp, err := stub.InvokeRpc(ctx, operation.GrpcObject.MethodDesc, message) if err != nil { // handle err } respMessage := dynamic.NewMessage(operation.GrpcObject.ResponseDesc) // descriptor from parser respMessage.ConvertFrom(resp) // convert message from raw response
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!