gRPC is not a magic bullet for the problems of state management. It'll have all the same issues RPC has had for the last 30 years in that it enforces no discipline where it counts, state management.
The real problem with REST is that state management across a distributed system is hard, real hard. So hard actually that we decide to ignore that it's a problem at all and instead get obsessed with client side interface code, transport protocol, or content types etc, the easy mechanical stuff.
gRPC wont be a magic bullet, just like CORBA wasn't, or XML-RPC, or SOAP. History does like to repeat itself...
I'm not saying they're hard questions. They're annoying, pointless questions that I have to answer every single time I create or consume a REST API. Those pointless questions also create very real bugs that I have dealt with for years, because humans make mistakes.
It's a complete waste of time and energy for everyone involved. Every one of these questions creates additional mental overhead and an opportunity for incorrect implementation. I would rather deal with meaningful decisions as often as possible, like questions of state management, instead of constantly deciding what color to paint the bike shed based on each person's interpretation of what "the most RESTy" API should look like.
You didn't seem to disagree with me in any way... I see nowhere in your comment where you say that REST APIs are better than gRPC, or why you would pick to make a REST API over gRPC or vice versa. Your rant just has nothing to do with my comment, as far as I can tell?
I never claimed that `gRPC` would solve state management. I never even mentioned state management.
So... cool? gRPC is not a magic bullet, I completely agree. It's a tool, and it seems to have advantages over REST APIs. That's what we're discussing here, since the OP asked why someone would use gRPC.
Your comment seems to imply that it's pointless to improve one problematic situation (RPC) without completely fixing all other problems in existence.
RPC (not just gRPC, but all its ancestors) as an architectural approach has the following problems that gRPC hasn't solved:
* It requires tight coupling between client and server
* It uses non standard naming and discovery which doesn't work across network boundaries, which is why SOAP and XML-RPC were invented, a way of channelling RPC over port 80/443.
* The problems of handling of state synchronization between client and server and the lack of standard failure and error modes.
* The lack of standards for caching of responses or middleware boxes for load balancing, rate limiting, deployment practices.
REST avoids these (and others) by:
* Using content negotiation and media types to communicate the format of requests and responses
* Using standard (DNS) naming and discovery network mechanisms
* Is a stateless protocol (between requests) that specifically expects that the client and server will exchange their states as part of each individual request. Being stateless, it accommodates network errors and the definitions of idempotency and limits on the number and types of verbs and reasonably strict definitions of their use also provide standard mechanisms for recovery.
* Specifically defines and accomodates naming, discovery, caching, chunking requests/replies, streaming, middleware cache and content distribution, network boundaries, security authentication and authorization etc.
Other than having an IDL that has tooling to generate stubs/clients in multiple languages, there are no distinct advantages of gRPC/protobuf over REST/HTTP, particularly in the general case of independent clients and servers from different organizations and user groups.
gRPC is a reasonable solution if your systems are able to be tightly coupled and deployed because they are either being developed as a monolith, or entirely within a common organization. If your network is reliable and not subject to interruption or partitioning between boundaries.
The entire "web services" saga of SOAP, WSDL, WS-* was an attempt 10-15 years ago to once again attempt RPC. So was RMI for Java. They failed for the same reasons.
People have been trying to "improve" RPC since the 80s, with numerous attempts and incarnations. They all suffer the same problems, which is that you cannot "wish away" the network by abstracting it out of existence.
The "annoying, pointless" questions of REST can be solved by not bikeshedding them each time, adopt JSON Schema, OpenAPI, JSON API and understand that REST is about the nouns, not the verbs. Limiting and strictly defining the operation of the verbs, which is what HTTP does, let's you focus on the nouns and how you want to "transfer the state" of the nouns between two endpoints. That's what REST is about.
It feels like maybe there us an excessive focus on the RPC in gRPC. You operate upon services, not objects like many traditional RPC systems (RMI, for example).
Do people really use gRPC in a stateful way? Wasn't one of the issues with old schools RPC that you pretended RPC objects were local objects? Here you do the opposite, aknowledge that objects are remote and you only have a copy of it locally.
> But if I'd like to remain a little more decoupled it's not very good at all.
It works quite well, IME. Each service publishes its protobuf files to a repository or registry during the build step, and if you want to call it from another service you just import the protobuf file and get a defined and documented interface with little to no boilerplate required to use. Protobuf has clear rules on how to evolve the interface in a backwards compatible way, so services can usually stay on the old definition until you need some new functionality, at which point you import the newest definitions.
https://github.com/uber-archive/idl defines a good workflow for this, though the tool is sadly unmaintained. Done right it really reduces the pain of crossing repository boundaries.
It doesn't solve the problem that RPC leaves the definition of the verbs (ie the procedures) and how they modify state of a common thing undefined. If I call an RP twice, what is the effect? How do I know it succeeded? What happens if it fails? etc etc
None of these things can be communicated through an IDL definition.
HTTP solves this problem by strictly defining the operation of its verbs (HEAD/OPTIONS/GET/PUT/POST/DELETE/PATCH) in terms of idempotency, caching, identification etc.
Communicating the structure of the things that you are manipulating in REST over HTTP is done by defining the media types that you expect and respond with. Content identification and headers in content/connection negotiation define the versions and formats of the content of requests and responses.
> But if I'd like to remain a little more decoupled it's not very good at all.
I don't really understand how gRPC makes this harder.
Either way, you have to call things correctly or they don't work. gRPC just naturally generates the client implementation for you, and it should always work. Swagger/OpenAPI theoretically help with this on the REST side of things, but it's up to the person publishing the Swagger as to whether it is actually 100% correct, or just a first order approximation.
But, I agree it's easier to have one protocol than two inside a company, so that would definitely be a downside of having both REST and gRPC in one organization.
> gRPC wont be a magic bullet, just like CORBA wasn't, or XML-RPC, or SOAP. History does like to repeat itself...
I will commend gRPC for being brave enough to attach "RPC" to its name in 2020. Can't say the same for that quisling GraphQL, which is neither what I would call a query language nor has anything to do with graphs. A- for marketing effort, I suppose.
> it enforces no discipline where it counts, state management
A tale as old as time. If your redux app is a bloated confusing mess, then try scaling down your department from 100 devs to the 10 that it actually needs. Most devs are bad at organization. Most devs are just bad in general. Ever see a bad developer grapple with TypeScript? I wager most codebases fall apart from disarray long before they reap any of the presumed benefits of most "best" practices. You can't fix social problems with technology. And code hygiene and state hygiene are fundamentally social issues. People think tools like Prettier can come around and clean their house for them. Like some Roomba for code. Even the best Roomba will smear dog shit all over the place.
I highly recommend you actually check out GraphQL. It definitely feels like it traverses relationships like a graph. It is more similar to a query language... like SQL actually because like SQL you can add more columns and more tables "similarly" and it really does join that data together.
It is actually a really good name. There are a lot of people that like to comment about that, but have never actually used it.
Sure, gRPC is no magic bullet that will solve all issues across your stack, but it is still a very solid tool/library. Using it instead of REST allows you quickly solve the easy problems (sending typed messages across the wire) while letting you focus on the hard parts (building distributed systems).
gRPC is a great way to implement a RESTful API [0]. Instead of saying `POST /thing` or `POST /things` or actually `PUT /thing` and maybe `POST /thing/1` you can say:
service ThingService {
rpc CreateThing(CreateThingRequest) returns (Thing);
rpc DeleteThing(DeleteThingRequest) returns (ThingDeleted); // No arguing about if this is within the HTTP spec and supported as it just works :)
rpc UpdateThing(...) returns (Thing);
rpc ListThings(...) returns (stream Thing);
}
Protobuf, thrift, avro, cap'n proto just off the top of my head. There is no shortage of RPC protocols and implementations and none of them have very wide adoption.
gRPC is not a magic bullet for the problems of state management. It'll have all the same issues RPC has had for the last 30 years in that it enforces no discipline where it counts, state management.
The real problem with REST is that state management across a distributed system is hard, real hard. So hard actually that we decide to ignore that it's a problem at all and instead get obsessed with client side interface code, transport protocol, or content types etc, the easy mechanical stuff.
gRPC wont be a magic bullet, just like CORBA wasn't, or XML-RPC, or SOAP. History does like to repeat itself...