Hacker News new | ask | show | jobs
by bairen 757 days ago
We built a backend heavily using protobufs/grpc and I highly regret it.

It ads an extra layer of complexity most people don't need.

You need to compile the protobufs and update all services that use them.

It's extra software for security scans.

Regular old http 1 rest calls should be the default.

If you are having scaling problem only then should you consider moving to grpc.

And even then I would first consider other simpler options.

3 comments

Personally I'll never go back to REST because you lose important typing information. The complexity doesn't go away. In the RPC/codegen paradigm the complexity is in the tooling and is handled by machines. In REST, it's in the minds of your programmers and gets sprinkled throughout the code.

> You need to compile the protobufs and update all services that use them.

You need to update all the services when you change your REST API too right? At least protobufs generates your code automatically for you, and it can do it as part of your build process as soon as you change your proto. Changes are backwards compatible so you don't even need to change your services until they need to change.

Its silly to think protobufs code gen is a advantage. I can take a json object/xml/csv from any API and plug it into a website that will spit out models in any language I want.

The only real advantage of grpc and protobufs have are speed and reduced data transmission.

And hey fair enough man if those are your bottle necks.

How will you know the generated model actually represents everything that can be in the API if you don't have a schema?
Sounds really like you used them for the wrong use case. If you are in need of a binary compact serialization, they are not prefect (is there any) but fair enough.
We ended up wrapping them in envoy so that our UI can convert the grpc to regular old http 1. And that's where they get the most use.

And by doing that we've added extra layers and it ended up slower than it would have been had we just used regular rest.

Further more now we need to keep evoy up to date.

Occasionally they break their API on major versions. Their config files are complicated and confusing.

So, imo, grpc should only be used for service to service communication where you don't want to share the code with a UI and speed and throughput is very very important.

And speed of http 1 rarely is the bottleneck.

But... Why? How is envoy, a proxy, related to your choice to use protobuf? How are your gripes with envoy relevant? This just smells like bad design
Yes, using envoy was bad design in our situation. It was premature optimisation.

We could either maintain a grpc API and a rest API , or a grpc API plus envoy, or 1 rest API.

I am saying we should have picked 1 rest API and only switched to grpc if and when we ran into scaling problems.

Avoiding having to maintain grpc compilers and envoy in our security updates.

Grpc isn’t just for scaling though. It’s a schema format that comes with code generation you can technically avoid the code generation if you so please.

Idk I think people are expecting either too much or too little of these tools.

So why did you choose to use grpc if you were just going to have to convert it?
We use a few of the endpoints in the backend. Service to service communication.

Those same endpoints are used with envoy. By our UI.

That choice was made to reduce code bloat.

Rather than maintain grpc and envoy it's easier to just maintain 1 rest API.

The service to service communication was never a bottle neck.

So it was highly prematurely optimized.

We spend way more time keeping evoy and our grpc compilers up to date and free of security issues than I would like.

It's just extra software and thus extra attack surfaces we didn't need. In retrospect

You don't need to compile the protobufs. The alternative, for all serialization formats, is to either load the schema dynamically, or write the handling logic manually yourself (or write your own generator/compiler).

gRPC supports HTTPv1 and can be mapped to a RESTful API (e.g. https://google.aip.dev/131).