Z fp
Z fp

Reputation: 574

How to unpack an google.protobuf.Any type in gRPC nodejs client?

My protobuf file is like this:

syntax = "proto3"; import "google/protobuf/any.proto";

service RoomService {
    getTestAny (Hotelid) returns (google.protobuf.Any); }

message Hotelid {
    string hotelid = 1; 
} 

message HtlInDate {
    Hotelid hotelid = 1;
    string date = 2; 
}

My java-gRPC-server code is like that:

@Override
public void getTestAny(Roomservice.Hotelid request, StreamObserver<Any> responseObserver) {

    Roomservice.Hotelid hotelid = Roomservice.Hotelid.newBuilder()
                                             .setHotelid("This is Hotelid")
                                             .build();

    Roomservice.HtlInDate htlDate = Roomservice.HtlInDate.newBuilder()
                                               .setHotelid(hotelid)
                                               .setDate("This is Data")
                                               .build();

    responseObserver.onNext(Any.pack(htlDate));
    responseObserver.onCompleted();
}

And I make a request from a nodejs-gRPC-client, which code is like that:

function () {
    var client = new services.RoomServiceClient('localhost:6565',
        grpc.credentials.createInsecure());

    var request = new messages.Hotelid();
    var hotelid = "ignore";

    request.setHotelid(hotelid);

    var call = client.getTestAny(request, function (err, response) {

        var obj = response.toObject();

        console.log(obj);
    });
}

The response in nodejs-gRPC-client is a type of Any. And it contains a data array:

array:["type.googleapis.com/HtlInDate", Uint8Array[10,17,10...]]

I try to use response.toObject() to get HtlInDate instance but I just get like this:

obj:{
   typeUrl:"type.googleapis.com/HtlInDate",
   value:"ChEKD1RoaXMgaXMgSG90ZWxpZBIMVGhpcyBpcyBEYXRh"
}

So how can I unpack the Any type response and get the HtlInDate instance exactly? Thanks a lot if you have any idea about this!

Upvotes: 12

Views: 6900

Answers (3)

Viacheslav Bilohlazov
Viacheslav Bilohlazov

Reputation: 31

From documentation: https://developers.google.com/protocol-buffers/docs/reference/javascript-generated#message

// Storing an arbitrary message type in Any.
const status = new proto.foo.ErrorStatus();
const any = new Any();
const binarySerialized = ...;
any.pack(binarySerialized, 'foo.Bar');
console.log(any.getTypeName());  // foo.Bar

// Reading an arbitrary message from Any.
const bar = any.unpack(proto.foo.Bar.deserializeBinary, 'foo.Bar');

Please take a note that for browser support you need to use webpack(probably with babel loader) or browserify

Upvotes: 2

David Goitia
David Goitia

Reputation: 69

As found in google-protobuf tests Any is bundled with pack and unpack functions.

Your code could be unpacked like this:

function () {
    var client = new services.RoomServiceClient('localhost:6565',
        grpc.credentials.createInsecure());

    var request = new messages.Hotelid();
    var hotelid = "ignore";

    request.setHotelid(hotelid);

    var call = client.getTestAny(request, function (err, response) {

        var obj = response.toObject();
        console.log('Any content', obj);

        var date = response.unpack(messages.HtlInDate.deserializeBinary, response.getTypeName());
        console.log('HtlInDate', date.toObject());
    });
}

This will deserialize the bytes received in the Any object.

You could also build some Any using pack function for wrapping TypeUrl and Value:

var someAny = new Any();
someAny.pack(date.serializeBinary(), 'HtlInDate')

Upvotes: 1

murgatroid99
murgatroid99

Reputation: 20297

Currently, the google.protobuf.Any type is not supported in Node.js, either in Protobuf.js, which gRPC uses by default, or by google-protobuf, which is the official first party protobuf implementation.

Upvotes: 2

Related Questions