-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gRPC - ContentSubType Support #7321
Comments
There is a blog about using a custom serializer/deserializer (JSON) https://grpc.io/blog/grpc-with-json/ which might be helpful? It doesn't mention registering using the contentSubType though. |
Yes, I've read that blog. It does help a bit. But it is a static solution for customizing serialization. And it doesn't change the fact that gRPC doesn't support multiple serialization methods at the same time in Java. But if we introduce in contentSubType, we can make multiple serializers available for clients choose, and server will response accordingly if it supports the same contentSubType. This solution would be much better than the current custom marshaller one. |
Java has Codec, CompressorRegistry and DecompressorRegistry which doesn't use contentSubType but rather the |
Thanks, @sanjaypujare . I will look into them. |
I'm afraid Codec doesn't meet my requirement. We do need a custom ser-deser support. And are we going to align the features of gRPC in all platforms? |
I am not aware of any efforts. CC @ejona86 for more info. |
@CH3CHO, grpc-java does not support the subtype thing; it is currently ignored and never sent. grpc-go added support for it thinking other languages supported it, when they don't. It would be possible to add, but would require additions to how If all you want to do is use a different codec type then you would change the MethodDescriptors to have the marshaller you want. That is similar to |
@ejona86 Our services have two types of client. One prefers performance and uses protobuf. The other prefers ease of use and uses json. The latter ones are usually QAs who have lots of Postman related test cases which are basically inputs and outputs encoded in json. Postman is heavily used in our company and Postman do not support protobuf yet😥. So it would really help a lot if we can support multiple codecs simultaneously. |
Okay. That's exactly the expected use-case (not the Postman not supporting protobuf, but some clients you want to be simpler/user-friendly). It will need API designs for both sending and receiving. Receiving is probably easier and is what you need. My thought-about-it-30-seconds design for receiving would be a subinterface of |
IMHO we should respond with HTTP status of 415 (Unsupported Media Type) as specified in the gRPC spec. I am not very familiar with the code. After some debugging, I think the core part to enable ContentSubType is in ServerCallImpl.java, specifically this line listener.onMessage(call.method.parseRequest(message));
// call is instance of ServerCallImpl where we parse the message with Marshaller. Actually in ServerCallImpl's constructor, we do have all the HTTP headers. ServerCallImpl(..., Metadata inboundHeaders, ...) {
//...
this.messageAcceptEncoding = inboundHeaders.get(MESSAGE_ACCEPT_ENCODING_KEY);
//...
} So we can save the content-type header in ServerCallImpl ServerCallImpl(..., Metadata inboundHeaders, ...) {
//...
this.messageAcceptEncoding = inboundHeaders.get(MESSAGE_ACCEPT_ENCODING_KEY);
this.messageContentType = inboundHeaders.get(CONTENT_TYPE_KEY);
//...
} and pass the content-type header to Marshaller. // replace this line with the following
//listener.onMessage(call.method.parseRequest(message));
MethodDescriptor.Marshaller<ReqT> marshaller = call.method.getRequestMarshaller();
String contentType = call.messageContentType; // the newly added field
if(marshaller instanceof MethodDescriptor.SubTypeAwareMarshaller && hasSubType(contentType)) {
// SubTypeAwareMarshaller is a subinterface of Marshaller
marshaller = ((MethodDescriptor.SubTypeAwareMarshaller)marshaller).getMarshallerForSubType(contentType);
}
listener.onMessage(marshaller.parse(message)); @ejona86 is the rough idea ok and can ServerCallImpl cover all the cases? |
* Move internal only classes to wvlet.airframe.http.grpc.internal * Add Metadata helper * Rename marshaller classes * Use Accept header instead as grpc-java doesn't support content-subtype * Add x-airframe-xxx-version header * Wrap generated clients with the default client interceptor * extract server factory * Wrap with GrpcResponse for setting JSON encoding * Add note about the missing support of content sub type: grpc/grpc-java#7321
I find that grpc-go support registering a custom codec and specifying a contentSubType when making a call.
Is it possible we support this feature in grpc-java so users can use custom serializers?
The text was updated successfully, but these errors were encountered: