protocolbuffers / protobuf-javascript

BSD 3-Clause "New" or "Revised" License
332 stars 66 forks source link

"Google Protobuf Any" javscript example #68

Open psaelango opened 6 years ago

psaelango commented 6 years ago

Can anyone please provide an example for https://developers.google.com/protocol-buffers/docs/proto3#any

I couldn't able to use the example provided in https://github.com/google/protobuf/issues/2612

xfxyjwf commented 6 years ago

Bo, we need to add documentation for Any API in javascript.

mwei0210 commented 5 years ago

Any documentation or guide for Any?

TeBoring commented 5 years ago
    var any = new proto.google.protobuf.Any();
    var msg = new proto.jspb.test.TestAllTypes();

    fillAllFields(msg);

    any.pack(msg.serializeBinary(), 'jspb.test.TestAllTypes');

    assertEquals('type.googleapis.com/jspb.test.TestAllTypes',
                 any.getTypeUrl());

    var msg2 = any.unpack(
        proto.jspb.test.TestAllTypes.deserializeBinary,
        'jspb.test.TestAllTypes');

    checkAllFields(msg, msg2);
TeBoring commented 5 years ago

https://github.com/google/protobuf/blob/master/js/binary/proto_test.js#L646-L662

chrisplusplus commented 5 years ago

Man the documentation for javascript is scarce. But for any one using the google-protobuf node module in angular, you can include the use of Any type in the below fashion. I recommend anyone using the javascript API to look through the tests because you won't find documentation as of yet.

var google_protobuf_any_pb = require('google-protobuf/google/protobuf/any_pb.js');
let any_pb = new google_protobuf_any_pb.Any;
clehene commented 5 years ago

@TeBoring I found the unit test, however I can't understand how that can be useful as documentation for how to actually use the code. Obviously if you have the actual message type of a byte string, you can deserialize it. You don't even need the type url string.

When consuming an Any field you only have access to the serialized byte string and the type URL. Hence you need to somehow get the actual type from the URL, which doesn't seem to be documented anywhere, unless I'm missing something.

Concretely, here's how the Java implementation looks like

    java.lang.Class<T> clazz)
      throws com.google.protobuf.InvalidProtocolBufferException {
    if (!is(clazz)) {
      throw new com.google.protobuf.InvalidProtocolBufferException(
          "Type of the Any message does not match the given class.");
    }
    if (cachedUnpackValue != null) {
      return (T) cachedUnpackValue;
    }
    T defaultInstance =
        com.google.protobuf.Internal.getDefaultInstance(clazz);
    T result = (T) defaultInstance.getParserForType()
        .parseFrom(getValue());
    cachedUnpackValue = result;
    return result;
  }
  public static final int TYPE_URL_FIELD_NUMBER = 1;
  private volatile java.lang.Object typeUrl_;

Is there an equivalent of com.google.protobuf.Internal.getDefaultInstance(clazz) for javascript?

chrisplusplus commented 5 years ago

I don't see any way in Javascript to do that. I work around this by including the type, as an enum, as part of my message struct and then using a switch case to properly unpack the any. Not dynamic I know, but it's the only way I know to do it.

clehene commented 5 years ago

@chrisplusplus that's what I ended up doing too

imraoarvind commented 2 years ago

Is there any way to dynamic create/use NestJs (gRPC/proto3) nestjs

dibenede commented 1 year ago

You need to know the type of the Any in order to work with it. There is intentionally no type registry and it's reasonable to use a map of a type -> constructor using getTypeName().

We can improve the documentation to better illustrate this.

chrisplusplus commented 1 year ago

One does not need to know that when using any other language. Only Javascript.

Is it not reasonable to assume the same thing can be accomplished in Javascript as well?

On Fri, Sep 23, 2022, 6:59 PM Stephanie DiBenedetto < @.***> wrote:

You need to know the type of the Any in order to work with it. There is intentionally no type registry and it's reasonable to use a map of a type -> constructor using getTypename().

We can improve the documentation to better illustrate this.

— Reply to this email directly, view it on GitHub https://github.com/protocolbuffers/protobuf-javascript/issues/68#issuecomment-1256781038, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEASPYAZWNQWDHYX2OE75LV7YY47ANCNFSM5WCL5V7Q . You are receiving this because you were mentioned.Message ID: @.***>

lukesandberg commented 1 year ago

Java Lite protos similarly don't provide registries to support any

The goal in both cases is the same, don't leak type names by default. As such it does shift a burden onto users.

chrisplusplus commented 1 year ago

What is the excuse for python? C++?

Perhaps I just don't understand why it is necessary to provide the string name of the message type to pack Any for Javascript but not Python. The capability to make it happen exists. It just isn't implemented.

On Fri, Sep 23, 2022, 8:10 PM Luke Sandberg @.***> wrote:

Java Lite protos similarly don't provide registries to support any

The goal in both cases is the same, don't leak type names by default. As such it does shift a burden onto users.

— Reply to this email directly, view it on GitHub https://github.com/protocolbuffers/protobuf-javascript/issues/68#issuecomment-1256809335, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEASP2CRB2ZDX4FGQXF35TV7ZBGLANCNFSM5WCL5V7Q . You are receiving this because you were mentioned.Message ID: @.***>

lukesandberg commented 1 year ago

This is intentionally unimplemented. You are correct that we could modify our generated code so that every message would know its own name and thus simply the pack API and others like it.

The tradeoff would be that it would 1. increase code size 2. leak type names for all types.

By forcing developers to pass these strings themselves, only the type names of any proto payloads are leaked (and they are already leaked by design).

For teams using this product to build websites it is, at least sometimes, important to ensure that features don't leak accidentally.

Other proto implementations make different tradeoffs because they have different target use-cases.