Skip to content(if available)orjump to list(if available)

gRPC vs. REST: Understand gRPC, OpenAPI and REST and When to Use in API Design

NAHWheatCracker

My only work experience with gRPC was on a project where another senior dev pushed for it because we "needed the performance". We ended up creating a JSON API anyways. Mostly because that's what the frontend could consume. No one except for that developer had experience with gRPC. He didn't go any deeper than the gRPC Python Quick start guide and wouldn't help fix bugs.

The project was a mess for a hundred reasons and never got any sort of scale to justify gRPC.

That said, I've used gRPC in bits outside of work and I like it. It requires lot more work and thought. That's mostly because I've worked on so many more JSON APIs.

lordofgibbons

That sounds more like a critique of the "senior" developer who didn't know grpc isn't compatible with browsers before adopting it than grpc itself.

NAHWheatCracker

Correct, I wasn't critiquing gRPC. I was critiquing a type of person who might push for gRPC. That developer probably thought of it as a novelty and made up reasons to use it. It was a big hassle that added to that teams workload with no upside.

bitzun

Unless you are doing bidirectional streaming (for which it seems pretty well suited, but I haven't used it, so it might be a fucking mess), grpc is usually a waste of time. Runtime transitive dependency hell, toolchain hell, and the teams inside Google that manage various implementations philosophically disagree on how basic features should work. Try exposing a grpc api to a team that doesn't use your language (particularly if they're using a language that isn't go, python or java, or is an old version of those.) Try exposing a grpc api to integrate with a cots product. Try exposing a grpc api to a browser. All will require a middleware layer.

lordofgibbons

I've used grpc at multiple companies and teams within these companies, all of them 100-500ish engineering team size, and never had these dependency and tool chain issues. It was smooth sailing with grpc.

aaomidi

Bidirectional streaming is generally a bad idea for anything you’re going to want to run “at scale” for what it’s worth.

rednafi

Google somehow psyoped the entire industry to use gRPC for internal service communications. The devex of gRPC is considerably worse than REST.

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.

lmm

> You can’t just give someone a simple command to call an endpoint—it requires additional tooling that isn’t standardized.

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.

nsonha

> GraphQL is even better

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?

sitzkrieg

i agree, was forced to use it at several companies and it was 99% not needed tech debt investment garbage

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

echelon

> The devex of gRPC is considerably worse than REST.

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.

danpalmer

I also disagree, at Google everything is RPCs in a similar way to gRPC internally, and I barely need to think about the mechanics of them most of the time, whereas with REST/raw HTTP, you need to think about so much of the process – connection lifecycle, keepalive, error handling at more layers, connection pools, etc.

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.

rednafi

My perspective stems from working with it in backend services as well. The type safety and the declarative nature of protobufs are nice, but writing clients and servers isn’t.

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.

recursivedoubts

> If your API is a REST API, then your clients never have to understand the format of your URLs and those formats are not part of the API specification given to clients.

Roy Fielding, who coined the term REST:

"A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations."

https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert...

I know it's a dead horse, but it's so funny: the "API specification" given to clients, in a truly RESTful system, should only be the initial entry point URI/URL.

eadmund

You both agree: when he writes ‘format of your URLs,’ he literally means the format of the URLs, not the format of the resources. Like you, I clicked on the article expecting yet another blogger who doesn’t understand REST but it appears this author has at least some basic knowledge of the concepts. Good for him!

I like gRPC too, and honestly for a commercial project it is pretty compelling. But for a personal or idealistic project I think that REST is preferable.

curt15

How does one even write an API client against a REST API that only publishes the initial entry point? in particular, how should the client discover the resources that can be manipulated by the API or the request/response models?

resonious

Classic case of a good idea going viral, followed by people misunderstanding the idea but continuing to spread it anyway.

gghoop

I dislike the use of gRPC within the data center. People reach for it citing performance, but gRPC is not high performance and the quality of the available open source clients is very poor, particularly outside of the core C++/Java implementations like the nodejs implementation. I am not against the use of protobuf as an API spec but it should be possible to use it with a framing protocol over TCP, there just isn't a clear dominant choice for that way of doing RPC. When it comes to web based APIs I am more in favour of readable payloads, but there are issues here since we tend to use JSON but the type specificity is loose, which leads to interop problems between backend languages, particularly in nodejs where JSON parse is used to implement a schema mapping. In order to do this properly, encoders and decoders need to be generated explicitly from schemas, which somewhat diminishes the use of JSON within the context of JS.

awinter-py

unless you want to be locked into a cursed ecosystem where you spend all your time reimplementing libraries that have existed for decades in rest land, fighting code generators that produce hideous classes that will randomly break compatibility, and debugging random edge-casey things in your hosting stack bc nobody truly supports h2, steer clear of grpc

'rest' isn't anything (complementary)

tyre

> The least-commonly used API model is REST—only a small minority of APIs are designed this way

brother.

mjr00

Technically they're right, though; the textbook definition of REST rare to nonexistent in my experience. What people do instead is create JSON-RPCs-over-HTTP APIs, sometimes following a REST-like URL scheme, and sometimes using different HTTP verbs on the same URL to perform different actions as one would in REST... but the API isn't really REST. The creator of REST has gone on the record multiple times about how you shouldn't call these APIs REST[0].

But in practice when most people say REST they just mean "JSON RPC over HTTP". I avoid calling things REST now and just use "JSON HTTP API" to avoid the "well, actually..." responses.

[0] https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert...

eadmund

Real REST is a very, very small minority.

Fake REST (i.e., JSON RPC) is really ridiculously common.

toprerules

As someone who has worked at a few of the FAANGs, having thrift/grpc is a godsend for internal service routing, but a lot of the complexity is managed by teams building the libraries, creating the service discovery layers, doing the routing etc. But using an RPC protocol enables those things to happen on a much greater scale and speed than you could ever do with your typical JSON/REST service. I've also never seen a REST API that didn't leak verbs. If I need to build a backend service mesh or wire two local services together via an networked stream, I will always reach for grpc.

That said, I absolutely would not use grpc for anything customer or web facing. RPC is powerful because it locks you into a lot of decisions and gives you "the one way". REST is far superior when you have many different clients with different technology stacks trying to use your service.

swyx

always felt like grpc was unnecessarily inaccessible to the rest of us outside google land. the grpc js client unnecessarily heavy and kinda opaque. good idea but poorly executed compared to people who are familiar with the "simplicity" of REST

masterj

You should check out https://connectrpc.com/ It's based on grpc but works a lot better with web tooling

kyrra

The official grpc JavaScript implementation is sort of bad. The one by buf.build is good from what I've seen.

https://buf.build/blog/protobuf-es-the-protocol-buffers-type...

limaoscarjuliet

There are uses where gRPC shines. Streaming is one of them - you can transparently send a stream of messages in one "connection". For simple CRUD service, REST is more than enough indeed.

tempest_

GRPC is a nice idea weighed down by the fact that it is full of solutions to google type problems I dont have. It seems like a lot of things have chosen it because a "binary" like rpc protocol with a contract is a nice thing to have but the further away from GoLang you get the worse it is.

rgbrgb

yes!

REST is kind of like HTML... source available by default, human-readable, easy to inspect

GRPC is for machines efficiently talking to other machines... slightly inconvenient for any human in the loop (whether that's coding or inspecting requests and responses)

The different affordances make sense given the contexts and goals they were developed in, even if they are functionally very similar.

dlahoda

afaik grpc did callbacks before we got sse/ws/webrtc/webtransport. so grpc was needed kind of.

and also canonical content streaming was in grpc. in http there was no common accepted solution at old times.

coder543

Your memory appears to be incorrect.

SSE was first built into a web browser back in 2006. By 2011, it was supported in all major browsers except IE. SSE is really just an enhanced, more efficient version of long polling, which I believe was possible much earlier.

Websocket support was added by all major browsers (including IE) between 2010 and 2012.

gRPC wasn't open source until 2015.

dilyevsky

Im old enough to have worked with asn.1 and its various proprietary “improvements” as well as SOAP/wsdl and compared to that working with protobuf/stubby (internal google predecessor to grpc) was the best thing since sliced bread

echelon

The frontend / backend split is where you have the REST and JSON camps fighting with the RPC / protobuf / gRPC factions.

RPCs have more maintainable semantics than REST as a virtue of not trying to shoehorn your data model (cardinality, relationships, etc.) into a one-size-fits-all prescriptive pattern. Very few entities ever organically evolve to fit cleanly within RESTful semantics unless you design everything upfront with perfect foresight. In a world of rapidly evolving APIs, you're never going to hit upon beautiful RESTful entities. In bigger teams with changing requirements and ownership, it's better to design around services.

The frontend folks don't maintain your backend systems. They want easy to reason about APIs, and so they want entities they can abstract into REST. They're the ultimate beneficiaries of such designs.

The effort required for REST has a place in companies that sell APIs and where third party developers are your primary customers.

Protobufs and binary wire encodings are easier for backend development. You can define your API and share it across services in a statically typed way, and your services spend less time encoding and decoding messages. JSON isn't semantic or typed, and it requires a lot of overhead.

The frontend folks natively deal with text and JSON. They don't want to download protobuf definitions or handle binary data as second class citizens. It doesn't work as cleanly with their tools, and JSON is perfectly elegant for them.

gRPC includes excellent routing, retry, side channel, streaming, and protocol deprecation semantics. None of this is ever apparent to the frontend. It's all for backend consumers.

This is 100% a frontend / backend tooling divide. There's an interface and ergonomic mismatch.

eadmund

Protobufs vs. JSON are orthogonal to REST vs. RPC: you can have REST where the representations are protobufs or JSON objects; you can have RPC where the requests and responses are protobufs or JSON objects.

dlahoda

there are well working (official) generators of openapi/json schemas for grpc.

so once you wrote grpc, you get open api rpc for free.

Glyptodon

According to this, what is GraphQL? This article seems like something written with limited or unusual experience.

Octoth0rpe

Oof, I strongly disagree with this article's description of how REST apis are used, and the distinction between openAPI and rest. If I design a REST api in 2023, and in 2024 produce an openapi yaml or json file for that API with no other changes, is it somehow no longer a REST api? of course not. The article seems to be predicated on this distinction.

> The least-commonly used API model is REST

Is that true? I don't think it is frankly, though I suppose if any API that would be a REST api _if it didn't have an openapi spec_ is somehow no longer a REST api, then maybe? But as previously stated, I just don't think that's true.

> A signature characteristic of [REST APIs] is that clients do not construct URLs from other information

I don't think this is true in practice. Let us consider the case of a webapp that uses a REST api to fetch/mutate data. The client is a browser, and is almost certainly using javascript to make requests. Javascript doesn't just magically know how to access resources, your app code is written to construct urls (example: getting an ID from the url, and then constructing a new url using that extracted ID to make an api call to fetch that resource). In fact, the only situation where I think this description of how a REST api is used is _defensibly_ true (and this is hella weak), is where the REST api in question has provided an openapi spec, and from that spec, you've converted that into a client library (example: https://openapi-ts.dev). In such a situation, the client has a nice set of functions to call that abstract away the construction of the URL. But somewhere in the client, _urls are still being constructed_. And going back to my first complaint about this article, this contrived situation combines what the article states are two entirely distinct methods for designing apis (rest vs openapi).

Re: the article's description of rpc, I actually don't have any major complaints.

golly_ned

This stood out to me as well. The author must have a particular understanding of REST that differs from the usual sense in which it’s used. He might be technically correct — I haven’t read the primary sources related to REST — but it distracted from the meat and potatoes of the article, which is really a comparison of gRPC and OpenAPI. It seemed very strange for this reason.

jijji

or he works for Google (author of gRPC) and is being paid to extol the virtues, albeit short sighted, of gRPC

silisili

You're being way too polite. The article is garbage and completely incorrect about what REST and OpenAPI even are.

turnsout

Yeah, the author has an extremely idiosyncratic take on the definition of REST which is either based on a misunderstanding, or a fundamentalist view of "pure" REST.

turnsout

I like this article format. Here, let me try. In my opinion, there are three significant and distinct formats for serializing data:

  - JSON
  - .NET Binary Format for XML (NBFX)
  - JSON Schema
JSON: The least-commonly used format is JSON—only a small minority use it, even though the word JSON is used (or abused) more broadly. A signature characteristic of JSON is the consumer of JSON can never know anything about the data model.

NBFX: A second serialization model is NBFX. The great thing about NBFX is that nobody has to worry about parsing XML text—they just have to learn NBFX.

JSON Schema: Probably the most popular way to serialize data is to use something like JSON Schema. A consumer of JSON Schema just reads the schema, and then uses JSON to read the data. It should be obvious that this is the total opposite of JSON, because again, in JSON it's illegal to know the format ahead of time.