Live data from Hacker News

gRPC: The Bad Parts

kmcd.dev

141–150 of 230 posts

Re: gRPC: The Bad Parts

#141

Earlier quoted context omitted.

Just out of curiosity, what domain were you working in where "0.0" and "no opinion" were _always_ the same thing? The lack of optionals has infuriated me for years and I just can't form a mental model of how anybody ever found this acceptable to work with.

Like nearly every time, empty string and 0 for integers can be treated the same as "no value" if you think about it. Are you sending data or sending opinions? Usually to force a choice, you would make a enum or a one-of where the zero-value means the client has forgotten to set it and it can be modelled as a api error. Whether the value was actually on the wire or not is not really that important.

Yeah, I think it's best to first rethink of null as just, not 0 and not any other number. What that means depends on the context.

Tangent: I've seen an antipattern of using enums to describe the "type" of some polymorphic object instead of just using a oneof with type-specific fields. Which gets even worse if you later decide something fits multiple types.

Re: gRPC: The Bad Parts

#142

I remember being surprised at how hard it was to read the source code for grpc Java. There's an incredible amount of indirection at every turn. This made it extremely hard to get answers to questions that were undocumented. It's a shame because I know Google can put out easy to read code (see: the go standard library).

Some of the details inside protobuf in Java can be very convoluted, but they are also the result of intense benchmarking, years of experiences and a long tail with deep legacy support for old java.

Honestly I found the Java bindings to be way better designed and thought out than Golang. On a consumer level, the immutable message builders are fantastic, the one-ofs are decent compared to what Java can offer, and the service bindings actually provide a beautiful abstraction with their 0-1-many model. In Golang, if you only have to deal with Unary rpc they are OK I guess, but I really miss the immutable messages.

Re: gRPC: The Bad Parts

#143

Earlier quoted context omitted.

Like nearly every time, empty string and 0 for integers can be treated the same as "no value" if you think about it. Are you sending data or sending opinions? Usually to force a choice, you would make a enum or a one-of where the zero-value means the client has forgotten to set it and it can be modelled as a api error. Whether the value was actually on the wire or not is not really that important.

Yeah, I think it's best to first rethink of null as just, not 0 and not any other number. What that means depends on the context. Tangent: I've seen an antipattern of using enums to describe the "type" of some polymorphic object instead of just using a oneof with type-specific fields. Which gets even worse if you later decide something fits multiple types.

I love oneofs in the language with good support, but they are woeful in Golang and the "official" grpc-web message types.

Re: gRPC: The Bad Parts

#144
post #46

I remember being surprised at how hard it was to read the source code for grpc Java. There's an incredible amount of indirection at every turn. This made it extremely hard to get answers to questions that were undocumented. It's a shame because I know Google can put out easy to read code (see: the go standard library).

The generated C++ interfaces to gRPC are also filled with an incredible amount of indirection and unnecessary concepts. I'd say it's a "bad at writing complex things simply" culture rather than being Java-specific.

Autogenerated code in general tends to be unreadable. It's not easy and/or not a priority.

Re: gRPC: The Bad Parts

#145

Yes, all of it. Google claims gRPC with protobuf yields a 10-11x performance improvement over HTTP. I am skeptical of those numbers because really it comes down to the frequency of data parsing into and out of the protobuf format. At any rate just use JSON with WebSockets. Its stupid simple and still 7-8x faster than HTTP with far less administrative overhead than either HTTP or gRPC.

I dont even care about the performance. I just want some way to version my messages that is backward and forwards compatible and can be delivered in all the languages we use in production. I have tried to consume json over websockets before and its always a hassle with the evolution of the data format. Just version it in protobuf and push the bytes over websocket if you have a choice. Also, load balancing web socket services can be a bitch. Just rolling out our web socket service would disconnect 500k clients in 60 seconds if we didnt make huge amounts of work.

Re: gRPC: The Bad Parts

#146
post #37

Re. bad tooling. grpcurl[1] is irreplaceable when working with gRPC APIs. It allows you to make requests even if you don't have the .proto around. [1]: https://github.com/fullstorydev/grpcurl

I just build a cli in Java or Go. It literally takes minutes to build a client.

Re: gRPC: The Bad Parts

#147
post #69

Earlier quoted context omitted.

That decision seems practical (especially at Google scale). I think the main problem with it, is that you cannot distinguish if the field has the default value or just wasn't set (which is just error prone). However, there are solutions to this, that add very little overhead to the code and to message size (see e.g. [1]). [1]: https://protobuf.dev/programming-guides/dos-donts/

The choice to make 'unset' indistinguishable from 'default value' is such an absurdly boneheaded decision, and it boggles my mind that real software engineers allowed proto3 to go out that way. I don't get what part of your link I'm supposed to be looking at as a solution to that issue? I wasn't aware of a good solution except to have careful application logic looking for sentinel values? (which is garbage)

Yes, proto3 as released was garbage, but they later made it possible to get most proto2 behaviors via configuration.

Re: your question, for proto3 an field that's declared as "optional" will allow distinguishing between set to default vs. not set, while non-"optional" fields don't.

Re: gRPC: The Bad Parts

#148
post #118

gRPC is deliberately designed not to be dependent on protobuf for its message format. It can be used to transfer other serialization formats. However, the canonical stub generator, which is not hard to replace at all, assumes proto so when people hear gRPC they really think of Protobuf over gRPC. Most of the complaints should be directed at protobuf, with or without gRPC. The primary misfeature of gRPC itself, irresp…

This is the true design issue with gRPC as I see it. It would be way bigger without this. I love protobuf though, gRPC is just alright. At least gRPC makes it so much simpler to build powerful automation and tooling around it than the wild west of randomly created 'json'-ish REST-ish APIs.

Re: gRPC: The Bad Parts

#149

The worst part of all is that most people don’t need gRPC, but use it anyway. It’s a net addition of complexity and you’re very likely not getting the actual benefits. I’ve seen countless simple REST APIs built with language-native tooling burned to the ground to be replaced with layers of gRPC trash that requires learning multiple new tools and DSLs, is harder to troubleshoot and debug, and ultimately tends to force…

People use it - like I do - because they like the improved type safety compared to REST. We use gRPC at $dayjob and I would hate going back to the stringly typed mess that is JSON over REST or the _really_ absurdly over engineered complexity trap that is GraphQL. gRPC lets us build type safe, self-documented internal APIs easily and with tooling like Buf, most of the pain is hidden. The DSL I consider a plus. If you…

This, 100%. I am never going back to stringly typed JSON in whatever random url structure that team felt like doing that week. GraphQL is made for Facebook type graph problems. Its way overcomplicated for most use cases. I just want a lingua franca DSL to enforce my API specification in a consistent manner. I dont care if its PUT POST PATCH. Just keep it easy to automate tooling.

Re: gRPC: The Bad Parts

#150

Earlier quoted context omitted.

Just out of curiosity, what domain were you working in where "0.0" and "no opinion" were _always_ the same thing? The lack of optionals has infuriated me for years and I just can't form a mental model of how anybody ever found this acceptable to work with.

Like nearly every time, empty string and 0 for integers can be treated the same as "no value" if you think about it. Are you sending data or sending opinions? Usually to force a choice, you would make a enum or a one-of where the zero-value means the client has forgotten to set it and it can be modelled as a api error. Whether the value was actually on the wire or not is not really that important.

0 as a default for "no int" is tolerable, 0.0 as a default for "no float" is an absolute nightmare in any domain remotely related to math, machine learning, or data science.

We dealt with a bug that for weeks was silently corrupting the results of trials pitting the performance of various algos against each other. Because a valid response was "no reply/opt out", combined with a bug in processing the "opt out" enum, also combined with a bug in score aggregation, functions were treated like they replied "0.0" instead of "confidence = None".

It really should have defaulted NaN for missing floats.

Post reply on HN