Server reflection fails when using well-known types (Timestamp)
ewrogers opened this issue · comments
Problem
Server reflection fails when using google.protobuf.*
well-known types such as Timestamp
or Duration
, requiring them to be registered by the server as well for grpcurl
to work properly.
Setup
I am using grpc-js
with NestJS integration along with @grpc/reflection
to register all my .proto
files on startup. It works exactly like their example. I also use ts-proto for generating the TypeScript interfaces from my .proto
files.
I can grpcurl localhost:5051 list
to see my services as expect:
$ grpcurl -plaintext localhost:5051 list
core.Organizations
core.Users
However, once I try to list one that uses a Timestamp
message I get the following error:
$ grpcurl -plaintext localhost:5051 list core.Organizations
Failed to list methods for service "core.Organizations": proto: message field "core.Organization.createdAt" cannot resolve type: "*.google.protobuf.Timestamp" not found
Interestingly, if I test it using the -import-path
and -proto
flags then it works fine!
$ grpcurl -plaintext -import-path ./proto -proto organizations.proto localhost:5051 describe core.Organizations
core.Organizations is a service:
service Organizations {
rpc GetOrganization ( .core.GetByIdRequest ) returns ( .core.Organization );
rpc GetOrganizationProfile ( .core.GetByIdRequest ) returns ( .core.OrganizationProfile );
}
$ grpcurl -plaintext -import-path ./proto -proto organizations.proto localhost:5051 describe core.Organization
core.Organization is a message:
message Organization {
string id = 1;
string displayName = 2;
optional string description = 3;
string type = 4;
string profileUsername = 5;
repeated .core.OrganizationProfileInfo profiles = 6;
.core.OrganizationContact contact = 7;
.core.OrganizationAddress address = 8;
optional string countryCode = 9;
optional string phoneNumber = 10;
optional string emailAddress = 11;
.google.protobuf.Timestamp createdAt = 12;
.google.protobuf.Timestamp updatedAt = 13;
}
I do not have any local copies of the Google well-known type .protos
and my import looks like this in organizations.proto
:
syntax = "proto3";
import "google/protobuf/timestamp.proto";
import "common.proto";
package core;
Expectation
That grpcurl
would have the Google well-known types pre-registered so that server reflection does not need to register them, which seems a bit redundant.
requiring them to be registered by the server as well for grpcurl to work properly
@ewrogers, I'm afraid that this is expected. It seems a little strange to me that registering your service wouldn't automatically register all of its dependencies. I'm not too familiar with grpc-js, but that is certainly how other runtimes work.
The support for builtin versions when using proto source files is only provided to for consistency with protoc
: you can generally compile files without providing these "well-known imports" since they are included with the compiler. But they are only there for compiling schemas from source. If you already have the schema in a compiled form (a file descriptor set or server reflection), that other source is authoritative and there should be no need to use them.
Just ran into the same issue, again using @grpc/reflection
:
> grpcurl -plaintext localhost:5081 describe
Failed to resolve symbol "module.ServiceName": proto: message field "module.MessageName" cannot resolve type: "*.google.protobuf.Timestamp" not found
This is when loading the protoset output as described in https://github.com/fullstorydev/grpcurl?tab=readme-ov-file#protoset-files
Interestingly though I am able to view all the service reflection information using Postman's GRPC Server Reflection feature with no issues, so I'm unclear as to why Postman is able to work with this but grpcurl is not.
My guess would be that certain gRPC clients "auto-import" these into their reflection engine.