* 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.
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.
REST is definitely not a magic bullet either because more often than not we fail to do that hard modelling aspect well enough.
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.
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.
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.
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.