Usage of custom options
Problem description
How do I get defined custom options from messages and services? The messages and service objects from output has options properties, but it is always null.
Reproduction steps
- Run
npm init -yin a new directory - Run
npm install @grpc/[email protected] -
main.js
const proto = require('@grpc/proto-loader') const util = require('util') const definition = proto.loadSync('main.proto') console.log('MyService: ', util.inspect(definition.MyService, false, 1000, true)) console.log('MyMessage: ', util.inspect(definition.MyMessage, false, 1000, true)) -
main.proto
syntax = "proto3"; import "google/protobuf/descriptor.proto"; extend google.protobuf.MessageOptions { string my_option = 51234; } service MyService { rpc MyRpc(MyMessage) returns (MyMessage) { option (my_option) = "Hello world!"; } } message MyMessage { option (my_option) = "Hello world!"; } - Run
node main.js - The output doesn't contain any info about custom options.
Environment
- OS name, version and architecture: [Windows 10 64x 20H2]
- Node version [v14.16.1]
- Node installation method [website]
- If applicable, compiler version []
- Package name and version [@grpc/[email protected]]
Additional context
@grpc/grpc-js does not add any additional data about custom options.
Console output: https://gist.githubusercontent.com/tscpp/32f889a1989b8f86e6a91af507438b53/raw/6973cab8d80dafcd2a94eff3ace1305ae133fd86/log.txt
You are correct, @grpc/proto-loader does not currently output information about custom options.
Is there any progress on this feature request? Would be great to see it on the next Roadmap. Thanks
@murgatroid99 Is it possible to upvote custom message options? Thanks
Are there any news to access custom service and method options via @grpc/proto-loader? Is this feature available in new protobufjs (7.xx) versions? @desytech: Do you have you found any workarounds to access options in node?
I also would like to access custom options from a package definition returned by protoLoader.load. It seems like the current protobufjs version 7.x. already supports parsing (custom) options from proto files. Thus the protobufjs objects passed to proto-loader's functions like createMethodDefinition or createServiceDefinition already have those options. So I think the only thing that needs to be done is to add the options to the returned definitions.
The following patch works for me (@grpc/proto-loader 0.7.10 - only tested with custom method options):
diff --git a/node_modules/@grpc/proto-loader/build/src/index.js b/node_modules/@grpc/proto-loader/build/src/index.js
index 5bbf6b3..1f5da21 100644
--- a/node_modules/@grpc/proto-loader/build/src/index.js
+++ b/node_modules/@grpc/proto-loader/build/src/index.js
@@ -99,10 +99,13 @@ function createMethodDefinition(method, serviceName, options, fileDescriptors) {
originalName: camelCase(method.name),
requestType: createMessageDefinition(requestType, fileDescriptors),
responseType: createMessageDefinition(responseType, fileDescriptors),
+ _options: method.options || {},
};
}
function createServiceDefinition(service, name, options, fileDescriptors) {
- const def = {};
+ const def = {
+ _options: service.options || {},
+ };
for (const method of service.methodsArray) {
def[method.name] = createMethodDefinition(method, name, options, fileDescriptors);
}
@@ -114,6 +117,7 @@ function createMessageDefinition(message, fileDescriptors) {
format: 'Protocol Buffer 3 DescriptorProto',
type: messageDescriptor.$type.toObject(messageDescriptor, descriptorOptions),
fileDescriptorProtos: fileDescriptors,
+ _options: message.options || {},
};
}
function createEnumDefinition(enumType, fileDescriptors) {
@@ -122,6 +126,7 @@ function createEnumDefinition(enumType, fileDescriptors) {
format: 'Protocol Buffer 3 EnumDescriptorProto',
type: enumDescriptor.$type.toObject(enumDescriptor, descriptorOptions),
fileDescriptorProtos: fileDescriptors,
+ _options: enumType.options || {},
};
}
/**
@murgatroid99, is it really that simple or did I miss something? Would you accept a PR for this?
@n0v1 The main problem is the types. I suggest looking at #2230, and the comments in particular, for a previous attempt at this. In short, the type of the options field from Protobuf.js is actually fairly complicated, and it has a lot of ambiguity that we can avoid here. I would only want to include the options if we can define the types as narrowly as possible.
Thanks for pointing at the existing pull request. Let's continue the discussion there. I might find some time to work on this.