You can’t just give someone a simple command to call an endpoint—it requires additional tooling that isn’t standardized. Plus, the generated client-side code is some of the ugliest gunk you’ll find in any language.
You can’t just give someone a simple command to call an endpoint—it requires additional tooling that isn’t standardized. Plus, the generated client-side code is some of the ugliest gunk you’ll find in any language.
Hard disagree from the backend world.
From one protocol change you can statically determine which of your downstream consumers needs to be updated and redeployed. That can turn weeks of work into a hour long change.
You know that the messages you accept and emit are immediately validated. You can also store them cheaply for later rehydration.
You get incredibly readable API documentation with protos that isn't muddled with code and business logic.
You get baked in versioning and deprecation semantics.
You have support for richer data structures (caveat: except for maps).
In comparison, JSON feels bloated and dated. At least on the backend.
However, I used to work in a company that used HTTP internally, and moving to gRPC would have sucked. If you're the one adding gRPC to a new service, that's more of a pain than `import requests; requests.get(...)`. There is no quick and hacky solution for gRPC, you need a fully baked, well integrated solution, rolled out across everyone who will need it.
Following up a "how do I experiment with this in my workflow" with "oh you don't need to" is not the greatest look. There is a vast portion of programming bugs that stem from someone misunderstanding what a given API does, so the ability to quickly self-verify that one is doing things right is essential.
The tooling is rough, and the documentation is sparse. Not saying REST doesn’t have its fair share of faults, but gRPC feels like a weird niche thing that’s hard to use for anything public-facing. No wonder none of the LLM vendors offer gRPC as an alternative to REST.
The same is achievable with a registry of OpenAPI documents. The only thing you need to ensure is that teams share schema definitions. This holds for gRPC as well. If teams create new types just copying some of the fields they need your analysis will be lost as well.
I mean, ideally (hopefully) in the JSON case there's some class defined in code that they can document in the comments
If it's a shitty shop that's sometimes less likely. Nice thing about protos is that the schemas are somewhere
GRPC is a standard in all the ways that matter. It (or Thrift) is a breath of fresh air compared to doing it all by hand - write down your data types and function signatures, get something that you can actually call like a function (clearly separated from an actual function function - as it should be, it behaves differently - but usable like one). Get on with your business logic instead of writing serialisation/deserialisation boilerplate. GraphQL is even better.
Letting clients introduce load into the system without understanding the big O impact of the SOA upstream is a foot gun. This does not scale and results in a massive waste of money on unnecessary CPU cycles on O(log n) FK joins and O(n^2) aggregators.
Precomputed data in the shape of the client's data access pattern is the way to go. Frontload your CPU cycles with CQRS. Running all your compute at runtime is a terrible experience for users (slow, uncachable, geo origin slow too) and creates total chaos for backend service scaling (Who's going to use what resource next? Nobody knows!).
If your REST API doesn't have a mechanism for each request to specify which related resources get included, you'll also be wasting resources include related resources which some requesters don't even need!
If your REST API does have a mechanism for each to request to specify which related sources get included (e.g. JSON API's 'include' query param [0]), then you have the same problem as GraphQL where it's not trivial to know the precise performance characteristics of every possible request.
just a casual sentence at the end? How about no. It's in the name, a query-oriented API, useless if you don't need flexible queries.
Why don't you address the problem they talked about, what is the cli tool I can use to test grpc, what about gui client?
In general though I agree devex for gRPC is poor. I primarily work with the Python and Go APIs and they can be very frustrating. Basic operations like "turn pbtypes.Timestamp into a Python datetime or Go time.Time" are poorly documented and not obvious. proto3 removing `optional` was a flub and then adding it back was an even bigger flub; I have a bunch of protos which rely on the `google.protobuf.Int64Value` wrapper types which can never be changed (without a massive migration which I'm not doing). And even figuring out how to build the stuff consistently is a challenge! I had to build out a centralized protobuf build server that could use consistent versions of protoc plus the appropriate proto-gen plugins. I think buf.build basically does this now but they didn't exist then.
No need to be snarky; that API did not exist when I started using protobuf. The method was called `TimestampProto` which is not intuitive, especially given the poor documentation available. And it required error handling which is unergonomic. Given that they switched it to timestamppb.New, they must've agreed with me. https://github.com/golang/protobuf/blame/master/ptypes/times... <-- and you can still see the full code from this era on master because of the migration from `github.com/golang/protobuf` to `google.golang.org/protobuf`, which was a whole other exercise in terrible DX.
Right but, the typical web service at the typical startup does need flexible queries. I feel people both overestimate its implications and under estimate its value.
- Standard "I need everything" in the model call
- Simplified "I need two properties call", like id + display name for a dropdown
- I need everything + a few related fields, which maybe require elevated permissions
GraphQL makes that very easy to support, test, and monitor in a very standard way. You can build something similar with REST, its just very ergonomic and natural in GraphQL. And its especially valuable as your startup grows, and some of your services become "Key" services used by a wider variety of use cases. Its not perfect or something everyone should use sure, but I believe a _lot_ of startup developers would be more efficient and satisfied using GraphQL.I'm convinced at this point that GraphQL only works effectively at a small scale, where inefficient queries aren't disastrously slow/heavy, OR at a large enough scale where you can dedicate at least an entire team of engineers to constantly tackle performance issues, caching, etc.
To me it also makes no sense at startups, which don't generally have such a high wall between frontend and backend engineering. I've seen it used at two startups, and both spent way more time on dealing with GraphQL BS than it would have taken to either ask another team to do query updates or just learn to write SQL. Indeed, at $CURRENT_JOB the engineering team for a product using GraphQL actively pushed for moving away from it and to server-side rendering with Svelte and normal knex-based SQL queries, despite the fact that none of them were backend engineers by trade. The GraphQL was just too difficult to reason about from a performance perspective.
> To me it also makes no sense at startups, which don't generally have such a high wall between frontend and backend engineering.
Startups are where I've seen it work really well, because it's the same team doing it and you're always solving the same problem either way: this page needs this data, so we need to assemble this data (and/or adjust what we actually show on this page) out of the database we have, and add appropriate indices and/or computed pre-aggregations to make that work. Even if you make a dedicated backend endpoint to provide that data for that page, you've still got to solve that same problem. GraphQL just means less boilerplate and more time to focus on the actual business logic - half the time I forgot we were even using it.
The client is the easy part if you just want to test calls.
It's actually still nice even if you don't use the flexibility. Throw up GraphiQL and you've got the testing tool you were worried about. (Sure, it's not a command line tool, but people don't expect that for e.g. SQL databases).
Use https://connectrpc.com/ and then you can use curl, postman, or any HTTP tool of your choosing that supports sending POST requests.
even in go its a pain in the ass to have to regen and figure out versioning shared protos and it only gets worse w each additional language
but every startup thinks they need 100 microservices and grpc so whatever
The secret is: don't worry about it. There is no need to regenerate your proto bindings for every change to the protos defs. Only do it when you need to access something new in your application (which only happens when you will be making changes to the application anyway). Don't try and automate it. That is, assuming you don't make breaking changes to your protos (or if you do, you do so under a differently named proto).