Live data from Hacker News

Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

cloud.google.com

241–250 of 286 posts

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#241

Earlier quoted context omitted.

Protobuf is an atrocious protocol. Whatever other problems gRPC has may be worse, but Protobuf doesn't make anything better that's for sure. The reason to use it may be that you are required to by the side you cannot control, or this is the only thing you know. Otherwise it's a disaster. It's really upsetting that a lot of things used in this domain are the first attempt by the author to make something of sorts. So m…

Agree. As an example, this proto generates 584 lines of C++, links to 173k lines of dependencies, and generates a 21Kb object file, even before adding grpc: syntax = "proto3"; message LonLat { float lon = 1; float lat = 2; } Looking through the generated headers, they are full of autogenerated slop with loads of dependencies, all to read a struct with 2 primitive fields. For a real monorepo, this adds up quickly.

This is because protobuf supports full run-time reflection and compact serialization (protobuf binary objects are not self-describing), and this requires a bit of infrastructure.

This is a large chunk of code, but it is a one-time tax. The incremental size from this particular message is insignficant.

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#242
post #30

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 (parti…

> Try exposing a grpc api to a team that doesn't use your language

Because of poor HTTP/2 support in those languages? Otherwise, it's not much more than just a run of the mill "Web API", albeit with some standardization around things like routing and headers instead of the randomly made up ones you will find in a bespoke "Look ma, I can send JSON with a web server" API. That standardization should only make implementing a client easier.

If HTTP/2 support is poor, then yeah, you will be in for a world of hurt. Which is also the browser problem with no major browser (and maybe no browser in existence) ever ending up supporting HTTP/2 in full.

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#243

I've been building API's for a long time, using gRPC, and HTTP/REST (we'll not go into CORBA or DCOM, because I'll cry). To that end, I've open sourced a Go library for generating your clients and servers from OpenAPI specs ( https://github.com/oapi-codegen/oapi-codegen ). I disagree with the way this article breaks down the options. There is no difference between OpenAPI and REST, it's a strange distinction. OpenAPI…

> To me, the problem with gRPC is proto files. Every client must be built against .proto files compatible with the server; it's not a discoverable protocol.

That's not quite true. You can build an OpenAPI description based on JSON serialization of Protobufs and serve it via Swagger. The gRPC itself also offers built-in reflection (and a nice grpcurl utility that uses it!).

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#244
post #30

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 (parti…

Nothing in Protobuf is suited for streaming. It's anti-streaming compared to almost any binary protocol you can imagine (unless you want to stream VHD, which would be a sad joke... for another time).

> Nothing in Protobuf is suited for streaming.

Uhh... Why? Protobuf supports streaming replies and requests. Do you mean that you need to know the message size in advance?

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#245
post #87

Earlier quoted context omitted.

Why do you say that? I'm involved in the planning for bidi streaming for a product that supports over 200M monthly active users. I am genuinely curious what landmines we're about to step on.

bidi streaming screws with a whole bunch of assumptions you rely on in usual fault-tolerant software: - there are multiple ways to retry - you can retry establishing the connection (e.g. say DNS resolution fails for a 30s window) _or_ you can retry establishing the stream - your load-balancer needs to persist the stream to the backend; it can't just re-route per single HTTP request/response - how long are your timeou…

> - there are multiple ways to retry - you can retry establishing the connection (e.g. say DNS resolution fails for a 30s window) _or_ you can retry establishing the stream

That's not how protobuf works? If a connection fails, you simply get an IO error instead of the next message. There is no machinery in gRPC that re-establishes connections.

You do need to handle timeouts and blocked connections, but that's a generic issue for any protocol.

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#246
post #172
post #30

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 (parti…

In my opinion, you shouldn't expose it to a browser, it's not what is good at, build something custom that converts to json. Like using REST to talk between backend services, makes no sense using a human readable protocol/api especially if there are performance requirements (not a call every now and then with a small amount of data returned).

To be fair, it was intended to be for browsers. But it was designed alongside the HTTP/2 spec, before browsers added HTTP/2 support, and they didn't anticipate that browsers wouldn't end up following the spec. So now it only works where you can rely on a spec-compliant HTTP/2 implementation.

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#247
post #87

Earlier quoted context omitted.

Why do you say that? I'm involved in the planning for bidi streaming for a product that supports over 200M monthly active users. I am genuinely curious what landmines we're about to step on.

bidi streaming screws with a whole bunch of assumptions you rely on in usual fault-tolerant software: - there are multiple ways to retry - you can retry establishing the connection (e.g. say DNS resolution fails for a 30s window) _or_ you can retry establishing the stream - your load-balancer needs to persist the stream to the backend; it can't just re-route per single HTTP request/response - how long are your timeou…

> - there are multiple ways to retry - you can retry establishing the connection (e.g. say DNS resolution fails for a 30s window) _or_ you can retry establishing the stream

This isn't a difficult problem to solve. We apply both of those strategies depending on circumstances. We can even re-connect clients to the same backend after long disconnection periods to support upload resuming etc.

> - your load-balancer needs to persist the stream to the backend; it can't just re-route per single HTTP request/response

This applies whether the stream is uni- or bi-directional. We already have uni-directional streams working well at scale, so this is not a concern.

> - how long are your timeouts? if you don't receive a message for 1s, OK, the client can probably keep the stream open, but what if you don't receive a message for 30s? this percolates through the entire request path, generally in the form of "how do I detect when a service in the request path has failed"

We maintain streams for very long periods. Hours or days. Clients can detect dropped streams (we propagate errors in both directions, although AWS ALBs are causing problems here) and the client knows how to re-establish a connection. And again this applies whether streams are uni- or bi-directional.

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#248

I've been building API's for a long time, using gRPC, and HTTP/REST (we'll not go into CORBA or DCOM, because I'll cry). To that end, I've open sourced a Go library for generating your clients and servers from OpenAPI specs ( https://github.com/oapi-codegen/oapi-codegen ). I disagree with the way this article breaks down the options. There is no difference between OpenAPI and REST, it's a strange distinction. OpenAPI…

> There is no difference between OpenAPI and REST, it's a strange distinction. That threw me off too. What the article calls REST, I understand to be closer to HATEOAS. > I've open sourced a Go library for generating your clients and servers from OpenAPI specs As a maintainer of a couple pretty substantial APIs with internal and external clients, I'm really struggling to understand the workflow that starts with gener…

This comes down to your philosophical approach to API development.

If you design the API first, you can take the OpenAPI spec through code review, making the change explicit, forcing others to think about it. Breaking changes can be caught more easily. The presence of this spec allows for a lot of work to be automated, for example, request validation. In unit tests, I have automated response validation, to make sure my implementation conforms to the spec.

Iteration is quite simple, because you update your spec, which regenerates your models, but doesn't affect your implementation. It's then on you to update your implementation, that can't be automated without fancy AI.

When the spec changes follow the code changes, you have some new worries. If someone changes the schema of an API in the code and forgets to update the spec, what then? If you automate spec generation from code, what happens when you express something in code which doesn't map to something expressible in OpenAPI?

I've done both, and I've found that writing code spec-first, you end up constraining what you can do to what the spec can express, which allows you to use all kinds of off-the-shelf tooling to save you time. As a developer, my most precious resource is time, so I am willing to lose generality going with a spec-first approach to leverage the tooling.

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#249
post #76

If I could go back in time I would stop myself from ever learning about gRPC. I was so into the dream, but years later way too many headaches. Don’t do it to yourself. Saying gRPC hides the internals is a joke. You’ll get internals all right, when you’re blasting debug logging trying to figure out what the f is going on causing 1/10 requests to fail and fine tuning 10-20 different poorly named and timeout / retry set…

What would you recommend doing instead?

Web sockets would probably be easy.

Some web socket libraries support automatic fallback to polling if the infrastructure doesn’t support web sockets.

Re: Understanding gRPC, OpenAPI and REST and when to use them in API design (2020)

#250
post #168

Earlier quoted context omitted.

There is a distinction between (proper) REST and what this blog calls "OpenAPI". But the thing is, almost no one builds a true, proper REST API. In practice, everyone uses the OpenAPI approach. The way that REST was defined by Roy Fielding in his 2000 Ph.D dissertation ("Architectural Styles and the Design of Network-based Software Architectures") it was supposed to allow a web-like exploring of all available resourc…

I tend to prefer RESTish rather than RESTful since RESTful almost suggests attempting to implement Fielding's ideas but not quite getting there. I think the subset of approaches that try and fail to implement Fielding's ideas is an order of magnitude (or two) smaller than those who go for something that is superficially similar, but has nothing to do with HATEOAS :-). REST is an interesting idea, but I don't think it…

While it is amazing for initial discovery to have everything presented for the developer's inspection, in production it ends up requiring too many network round-trips to actually traverse from root to /resource_name/resource_id/sub_resource_name/sub_resource_id, or an already verbose transaction (everything is serialized and deserialized into strings!) becomes gigantic if you if don't make it hierarchical and just drop every URL into the root response.

This is why everyone just builds magic URL endpoints, and hopefully also includes a OpenAPI/Swagger documentation for them so the developer can figure it out. And then keeps the documentation up-to-date as they add new sub_resource endpoints!

Post reply on HN