top | item 42800474

(no title)

jdwyah | 1 year ago

If I could go back in time I would stop myself from ever learning about gRPC. I was so into the dream, but years later way too many headaches. Don’t do it to yourself.

Saying gRPC hides the internals is a joke. You’ll get internals all right, when you’re blasting debug logging trying to figure out what the f is going on causing 1/10 requests to fail and fine tuning 10-20 different poorly named and timeout / retry settings.

Hours lost fighting with maven plugins. Hours lost debugging weird deadline exceeded. Hours lost with LBs that don’t like the esoteric http2. Firewall pain meaning we had to use Standard api anyway. Crappy docs. Hours lost trying to get error messages that don’t suck into observability.

I wish I’d never heard of it.

discuss

order

stickfigure|1 year ago

IMO the problem with gRPC isn't the protocol or the protobufs, but the terrible tooling - at least on the Java end. It generates shit code with awful developer ergonomics.

When you run the protobuf builder...

* The client stub is a concrete final class. It can't be mocked in tests.

* When implementing a server, you have to extend a concrete class (not an interface).

* The server method has an async method signature. Screws up AOP-oriented behavior like `@Transactional`

* No support for exceptions.

* Immutable value classes yes, but you have to construct them with builders.

The net result is that if you want to use gRPC in your SOA, you have to write a lot of plumbing to hide the gRPC noise and get clean, testable code.

There's no reason it has to be this way, but it is that way, and I don't want to write my own protobuf compiler.

Thrift's rpc compiler has many of the same problems, plus some others. Sigh.

bjackman|1 year ago

> The client stub is a concrete final class. It can't be mocked in tests.

I believe this is deliberate, you are supposed to substitute a fake server. This is superior in theory since you have much less scope to get error reporting wrong (since errors actually go across a gRPC transport during the test).

Of course.. at least with C++, there is no well-lit-path for actually _doing_ that, which seems bonkers. In my case I had to write a bunch of undocumented boilerplate to make this happen.

IIUC for Stubby (Google's internal precursor to gRPC) those kinda bizarre ergonomic issues are solved.

tbarbugli|1 year ago

In my experience, only Swift has a generator that produces good-quality code. Ironically, it’s developed by Apple.

rkagerer|1 year ago

Any alternatives that take a similar philosophy but get the tooling right?

crabbone|1 year ago

Protobuf is an atrocious protocol. Whatever other problems gRPC has may be worse, but Protobuf doesn't make anything better that's for sure.

The reason to use it may be that you are required to by the side you cannot control, or this is the only thing you know. Otherwise it's a disaster. It's really upsetting that a lot of things used in this domain are the first attempt by the author to make something of sorts. So many easily preventable disasters exist in this protocol for no reason.

dtquad|1 year ago

Your problems has more to do with some implementations than the grpc/protobuf specs themselves.

The modern .NET and C# experience with gRPC is so good that Microsoft has sunset its legacy RPC tech like WCF and gone all in on gRPC.

junto|1 year ago

Agreed. The newest versions of .NET are now chef’s kiss and so damn fast.

zigzag312|1 year ago

I would really like if proto to C# compiler would create nullable members. Hasers IMO give poor DX and are error prone.

hedora|1 year ago

The biggest project I’ve used it with was in Java.

Validating the output of the bindings protoc generated was more verbose and error prone than hand serializing data would have been.

The wire protocol is not type safe. It has type tags, but they reuse the same tags for multiple datatypes.

Also, zig-zag integer encoding is slow.

Anyway, it’s a terrible RPC library. Flatbuffer is the only one that I’ve encountered that is worse.

TeeWEE|1 year ago

What do you mean with validating the bindings? GRPC is type safe. You don’t have to think about that part anymore.

But as the article mentions OpenAPI is also an RPC library with stub generation.

Manual parsing of the json is imho really Oldskool.

But it depends on your use case. That’s the whole point: it depends.

matrix87|1 year ago

> The wire protocol is not type safe. It has type tags, but they reuse the same tags for multiple datatypes.

When is this ever an issue in practice? Why would the client read int32 but then all of a sudden decide to read uint32?

bborud|1 year ago

Since you mention Maven I'm going to make the assumption that you are using Java. I haven't used Java in quite a while. The last 8 years or so I've been programming Go.

Your experience of gRPC seems to be very different from mine. How much of the difference in experience do you think might be down to Java and how much is down to gRPC as a technology?

piva00|1 year ago

It's not Java itself, it's design decisions on the tooling that Google provides for Java, mostly the protobuf-gen plugin.

At my company we found some workarounds to the issues brought up on GP but it's annoying the tooling is a bit subpar.

divan|1 year ago

I use gRPC with Go+Dart stack for years and never experienced these issues. Is it something specific to Java+gRPC?

robertlagrant|1 year ago

Go and Dart are probably the languages most likely to work well with gRPC, given their provenance.

drtse4|1 year ago

As someone that used it for years with the same problems he describes... spot on analysis, the library does too much for you (e.g. reconnection handling) and handling even basic recovery is a bit a nuisance for newbies. And yes, when you get random failures good luck figuring out that maybe is just a router in the middle of the path dropping packets because their http2 filtering is full of bugs.

I like a lot of things about it and used it extensively instead of the inferior REST alternative, but I recommend to be aware of the limitations/nuisances. Not all issues will be simply solved looking at stackoverflow.

azemetre|1 year ago

What would you recommend doing instead?

Atotalnoob|1 year ago

Web sockets would probably be easy.

Some web socket libraries support automatic fallback to polling if the infrastructure doesn’t support web sockets.

doctorpangloss|1 year ago

Do you need bidirectional streams? If so, you should write a bespoke protocol, on top of UDP, TCP or websockets.

If you don't, use GraphQL.