Hacker News new | ask | show | jobs
by skywhopper 727 days ago
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 API rigidity far sooner than is healthy.

One project I worked on was basically just a system for sharing a JSON document to multiple other systems. This was at a golang shop on AWS. We could have used an S3 bucket. But sure, an API might be nice so you can add a custom auth layer or add server side filters and queries down the road. So we built a REST API in a couple of weeks.

But then the tech lead felt bad that we hadn’t used gRPC like the cool kids on other teams. What if we needed a Python client so we could build a Ansible plugin to call the API?? (I mean, Ansible plugins can be in any language; it’s a rest API, Ansible already supports calling that (or you could just use curl); or you could write the necessary Python to call the REST API in like three lines of code.) so we spent months converting to gRPC, except we needed to use the Connect library because it’s cooler, except it turns out it doesn’t support GET calls, and no one else at the company was using it.

By the time we built the entire service, we had spent months, it was impossible to troubleshoot, just calling the API for testing required all sorts of harnesses and mocks, no good CLI tooling, and we were generating a huge Python library to support the Ansible use case, but it turned out that wasn’t going to work for other reasons.

Eventually everyone on that team left the company or moved to other projects. I don’t think anything came of it all but we probably cost the company a million dollars. Go gRPC!

3 comments

> 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 API rigidity far sooner than is healthy.

This sounds odd to me because I don't really see how gRPC would cause any of those issues?

> layers of gRPC trash

What layers? Switching from REST (presumably JSON over http) to gRPC shouldn't introduce any new "layers". It's replacing one style of API call with a different one.

> learning multiple new tools and DSLs

New tools sure, you need protoc or buf to build the bindings from the IDL, but what is the new DSL you need to learn?

> ultimately tends to force API rigidity far sooner than is healthy

How does gRPC force API rigidity? It is specifically designed to be evolvable (sometimes to its usability detriment IMO)

There are some definite footguns with gRPC and I am becoming increasingly annoyed with Protobuf in particular as the years go on, but going back to REST APIs still seems like a huge step backwards to me. With gRPC you get a workflow that starts with a well-defined interface and all the language bindings client/server stubs are generated from that with almost zero effort. You can kind of/sort of do that with REST APIs using openapi specs but in my experience it just doesn't work that well and language support is sorely lacking.

> What layers? Switching from REST (presumably JSON over http) to gRPC shouldn't introduce any new "layers".

Of course it does, starting with the protobufs and code generation. You say yourself in your very next reply:

"New tools sure, you need protoc or buf to build the bindings from the IDL, but what is the new DSL you need to learn?"

And the DSL is presumably protobuf, which you yourself are "increasingly annoyed" with.

You need all the same stuff with a REST API only instead of using tooling to codegen all the boilerplate you have to write it by hand (or use janky OpenAPI code generators which, in my experience, rarely work very well).

I am increasingly annoyed by protobuf as a standalone format but given the choice to create a new API using gRPC (where I can spend five minutes writing some proto files and then codegen all the boilerplate I need for both server and client in any mainstream language) and creating it as a REST API where I have to manually code all the boilerplate and decide between a zillion different ways of doing everything I will choose gRPC 100% of the time.

> You need all the same stuff with a REST API

That's just not true. A straightforward REST API is significantly simpler and less code throughout.

How exactly? If we take the simplest possible "hello world" service, then protoc generates all the code for a gRPC service without you having to manually type anything
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 build REST APIs you will usually also resort to using a DSL to define your APIs, at least if you want to easily generate clients. But in this case the DSL is OpenAPI, which is an error prone mess of YAML or JSON specifications.

I use it because: 1. I am not writing a network API without a solid spec, and 2. I want to decouple the number of tcp connections from the amount of pending work. I don't want one wonky msg to consume many resources and I want a spike of traffic to cause more msgs to be sent to the worker pools not cause a bunch of TCP connection establishment, SSL handshakes, etc. I also find it personally offensive to send field names in each network msg, as per JSON or XML.
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.
> People use it - like I do - because they like the improved type safety compared to REST.

You don't need a binary format just to get type safety. JSONSchema, OpenAPI, etc exist after all.

> But in this case the DSL is OpenAPI, which is an error prone mess of YAML or JSON specifications.

They might not be pretty, but they're not particularly error prone (the specs themselves are statically checked).

YAML in any form is error prone and hard to write. Protobuf - for all its warts - is much easier to write And much more type safe.

But let’s just agree to disagree here. You do you and build REST APIs, while I’ll stick to gRPC

I’m not anti-protobuf; it’s just overkill for type safety. But yeah, use what you want.
This anecdote highlights scope creep and mismanagement, not a fault of gRPC.
I think the anecdote highlights that there's no incremental way to approach gRPC, it's not a low risk small footprint prototype project that can be introduced slowly and integrated with existing systems and environments. Which, well, it is a bit of a fault of gRPC.
I think that's not true. There are plenty of incremental ways to adopt gRPC. For example, there are packages that can facade/match your existing REST APIs[1][2].

Reads like a skill issue to me.

[1]: https://github.com/grpc-ecosystem/grpc-gateway [2]: https://github.com/connectrpc/vanguard-go