I think the problem you're running into is that unfortunately we don't
currently support proto3 JSON
<https://developers.google.com/protocol-buffers/docs/proto3#json> for
Javascript. Proto3 JSON is the JSON-based format that understands the
special representations for well-known types such as Struct and Any.

Actually gRPC's dynamic codegen uses protobuf.js
<https://github.com/dcodeIO/protobuf.js>, which is a totally separate
implementation from the main one we maintain at
https://github.com/google/protobuf. But neither implementation has support
for proto3 JSON, so if you're using Node.js then Struct, Value, and Any
won't be of much help for now.

Could you describe a bit more about what the metadata field needs to
contain? Does it really need to support completely arbitrary JSON or would
it possibly be something where there are just a handful of different basic
schemas you expect? If the field can be arbitrary JSON then perhaps the
best solution would be to just use a bytes field and store the raw JSON
blob inside it.

On Wed, Nov 16, 2016 at 10:47 AM, Bojan D <[email protected]> wrote:

> Here's a simpler server.js that doesn't require a client.js or deals with
> any of the grpc stuff really.
>
> const path = require('path')
> const grpc = require('grpc')
>
> const PROTO_PATH = path.resolve(__dirname, './user.proto')
> const HOSTPORT = '0.0.0.0:50051'
>
> const UserProto = grpc.load(PROTO_PATH);
> const User = UserProto.User
>
> const data = {
>   "[email protected]": {
>     "email": "[email protected]",
>     "firstName": "Bob",
>     "lastName": "Smith",
>     "metadata": {
>       "foo": "bar",
>       "active": true
>     }
>   },
>   "[email protected]": {
>     "email": "[email protected]",
>     "firstName": "Jane",
>     "lastName": "Smith"
>   }
> }
>
> function main() {
>   const u = new User(data['[email protected]'])
>   console.log(u)
> }
>
> main()
>
> change the email to '[email protected]' and it would crash.
>
> On Wednesday, 16 November 2016 14:38:55 UTC-4, Bojan D wrote:
>>
>> Sure sorry...
>>
>> I am working with node.js and trying to use grpc. Reproducible steps:
>>
>> Install node 6.9.1
>>
>> mkdir grpctest
>> cd grpctest
>> npm install grpc
>>
>> user.proto:
>>
>> import "google/protobuf/struct.proto";
>>
>> syntax = "proto3";
>>
>> package user;
>>
>> message User {
>>   string email = 1;
>>   string firstName = 2;
>>   string lastName = 3;
>>   google.protobuf.Value metadata = 4;
>> }
>>
>> message GetUserRequest {
>>   string email = 1;
>> }
>>
>> service UserService {
>>   rpc GetUser(GetUserRequest) returns (User);
>> }
>>
>> server.js:
>>
>> const path = require('path')
>> const grpc = require('grpc')
>>
>> const PROTO_PATH = path.resolve(__dirname, './user.proto')
>> const HOSTPORT = '0.0.0.0:50051'
>>
>> const UserService = grpc.load(PROTO_PATH).user.UserService
>>
>> const data = {
>>   "[email protected]": {
>>     "email": "[email protected]",
>>     "firstName": "Bob",
>>     "lastName": "Smith",
>>     "metadata": {
>>       "foo": "bar",
>>       "active": true
>>     }
>>   },
>>   "[email protected]": {
>>     "email": "[email protected]",
>>     "firstName": "Jane",
>>     "lastName": "Smith"
>>   }
>> }
>>
>> function getUser(call, callback) {
>>   const user = data[call.request.email]
>>   if (!user) {
>>     return callback(new Error('User Not Found'))
>>   }
>>   return callback(null, user)
>> }
>>
>> function main() {
>>   const server = new grpc.Server()
>>   server.addProtoService(UserService.service, { getUser })
>>   server.bind(HOSTPORT, grpc.ServerCredentials.createInsecure())
>>   server.start()
>>   console.log(`User service running @ ${HOSTPORT}`)
>> }
>>
>> main()
>>
>> client.js
>>
>> const path = require('path')
>> const grpc = require('grpc')
>>
>> const PROTO_PATH = path.resolve(__dirname, './user.proto')
>> const HOSTPORT = '0.0.0.0:50051'
>>
>> const UserService = grpc.load(PROTO_PATH).user.UserService
>> const client = new UserService(HOSTPORT, grpc.credentials.createInsecur
>> e())
>>
>> client.getUser({ email: '[email protected]' }, (err, user) => {
>>   console.log(user)
>>   process.exit()
>> })
>>
>>
>> Run the server using command:
>>
>> node server.js
>> User service running @ 0.0.0.0:50051
>>
>> Run the client:
>>
>> node client.js
>> { email: '[email protected]',
>>   firstName: 'Jane',
>>   lastName: 'Smith',
>>   metadata: null }
>>
>> change the email in client request to '[email protected]'
>>
>> /Users/bojand/dev/nodejs/grpctest/node_modules/protobufjs/
>> dist/protobuf.js:2472
>>                             throw Error(this+"#"+keyOrObj+" is not a
>> field: undefined");
>>                             ^
>>
>> Error: .google.protobuf.Value#foo is not a field: undefined
>>     at Error (native)
>> ...
>>
>> Within the server part once we load proto we do have a constructor for
>> the User class, and I've tried playing around with trying to create an
>> instance of that in different ways and it crashes when trying to create
>> that instance. I've also tried to encode from stringified JSON and still
>> fails. When there is "metadata" it crashes. I think I am doing something
>> dumb but I am not sure what.
>>
>> Thanks.
>>
>> On Wednesday, 16 November 2016 13:58:44 UTC-4, Tim Kientzle wrote:
>>>
>>> I think we need more details:
>>>
>>>    Are you using C++ or Java or Python or Ruby or C# or some other
>>> language?
>>>
>>>    What version of protoc?
>>>
>>>    Can you show the code you’re using to create the message?
>>>
>>> Tim
>>>
>>>
>>> On Nov 16, 2016, at 5:02 AM, Bojan D <[email protected]> wrote:
>>>
>>> Thanks for the answer. Somehow I missed the Protocol Buffers Well-Known
>>> Types page in the docs / protobuf website.
>>>
>>> I still have issue creating an instance of the message. For example if I
>>> have a plain object:
>>>
>>> {
>>>   firstName: 'Bob'
>>>   lastName: 'Smith',
>>>   email: '[email protected]',
>>>   metadata: {
>>>     foo: 'bar',
>>>     active: true
>>>   }
>>> }
>>>
>>> And I try to create an instance of the message (to be sent via grpc) I
>>> get error
>>>
>>> .google.protobuf.Struct#foo is not a field: undefined
>>>
>>> Same thing if I use google.protobuf.Value. I've tried numerous ways of
>>> doing this but can't seem to accomplish it. I must be missing something.
>>> Anyone have any ideas.
>>>
>>> Thanks for the help again.
>>>
>>> Bojan
>>>
>>> On Tuesday, 15 November 2016 15:57:20 UTC-4, Tim Kientzle wrote:
>>>>
>>>>
>>>> On Nov 15, 2016, at 9:15 AM, Bojan D <[email protected]> wrote:
>>>>
>>>> Newbie question... If I have the following sample "User" JSON data:
>>>>
>>>> {
>>>>   firstName: 'Bob'
>>>>   lastName: 'Smith',
>>>>   email: '[email protected]',
>>>>   metadata: {
>>>>     // a plain JS object that
>>>>     // - will always exist and be at least an empty {} object
>>>>     // - could potentially contain any number of properties and
>>>> values, depending on specific "user"
>>>>   }
>>>> }
>>>>
>>>> How do I represent the metadata property within proto definition?
>>>>
>>>>
>>>>
>>>> You want to use the well-known types “Struct” or “Value”, which are
>>>> specifically designed to support ad hoc JSON parsing.  “Struct” supports
>>>> parsing any valid JSON object structure, “Value” can parse any valid JSON:
>>>>
>>>> message User {
>>>>   string email = 1;
>>>>   string firstName = 2;
>>>>   string lastName = 3;
>>>>   google.protobuf.Struct metadata = 4;
>>>> }
>>>>
>>>>
>>>> Tim
>>>>
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Protocol Buffers" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at https://groups.google.com/group/protobuf.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>> --
> You received this message because you are subscribed to the Google Groups
> "Protocol Buffers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/protobuf.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.

Reply via email to