
gRPC-Web is going GA - biggestlou
https://www.cncf.io/blog/2018/10/24/grpc-web-is-going-ga/
======
_zachs
I'm still not sold on gRPC vs JSON/REST.

.proto offers me little over a decent development environment around JSON, and
it seems to be pretty Google-specific.

I'm also wary of adopting standards that come out of Google.

~~~
hsaliak
disclaimer: I work for the gRPC team.

gRPC lets you use other data exchange formats or IDLs as well, such as
flatbuffers. However, the protobuf codegen experience we have spent most of
the time and energy on.

I see two sides to this - on one hand, there are folks who want a 'contract
first' development experience, in which the service contracts are defined
first, and the business logic is implemented later. gRPC lends itself to this
model very well. Admittedly, this is also the way services are developed in
Google.

On the other hand, there are folks who want a model whereby you evolve a
service and generate the specs from that service. Currently, this is not the
experience that gRPC is optimized for. Time and effort are the main barriers
to making this work well alongside a contract-first experience. FWIW: I
believe both models have merit and it really depends on what you want to adopt
as the source of truth for how your services interact. Ideally, gRPC would be
good at both.

~~~
yashap
IMO json+REST works just as well for contract first workflows. Just write up
the contract in an IDL, have both sides agree on it up front, then use codegen
tools to generate client SDK(s) for your client language(s) of choice. Same
workflow as as with gRPC, though you’re probably less likely to get generated
server stubs (which you don’t really need with json+REST anyways).

~~~
ben_jones
Could you recommend any codegen tools that generate bindings in Typescript or
Go? I suppose there's some tools around swagger and various GraphQL libraries,
but I'm not seeing any great options though a quick google search.

~~~
ThePadawan
I have made negative experience with using a custom swagger-codegen [0]
template - the library is quite diffuse with no clear direction in which PRs
are merged and which aren't, making it a mess to read and extend. I have
however, managed to generate the exact Typescript bindings I wanted using it.

In contrast, I have been using NSwag [1] to generate C# client code with far
greater comfort, and it seems to support multiple Typescript clients already.

[0] [https://github.com/swagger-api/swagger-
codegen](https://github.com/swagger-api/swagger-codegen) [1]
[https://github.com/RSuter/NSwag](https://github.com/RSuter/NSwag)

~~~
wing328hk
Sorry to hear your negative experience with Swagger Codegen regarding the PRs.
Having been "managing" the project for a few years, I agree with you that I've
not done a very good job in reviewing and merging all the PRs (239 open PRs as
of today) contributed by the awesome community.

Myself and 40+ top contributors have decided to fork Swagger Codegen so as to
maintain a community-driven version called OpenAPI Generator [1] with a better
governance structure to move the project forward. Now there are 10+ core team
members and contributors with proper rights to merge PRs so I think we've
better PR management in OpenAPI Generator. Please refer to the Q&A [2] for the
reasons behind the fork.

For TypeScript generators, we've recently added the TypeScript Axios client
generator [3] and there's an ongoing project to consolidate the TypeScript
generators into one [4]. Please check these out and let us know if you've any
feedback.

We hope you will find OpenAPI Generator useful in your projects.

[1] [https://openapi-generator.tech](https://openapi-generator.tech) [2]
[https://github.com/OpenAPITools/openapi-
generator/blob/maste...](https://github.com/OpenAPITools/openapi-
generator/blob/master/docs/qna.md) [3]
[https://twitter.com/oas_generator/status/1041939441109983232](https://twitter.com/oas_generator/status/1041939441109983232)
[4] [https://github.com/OpenAPITools/openapi-
generator/projects/4](https://github.com/OpenAPITools/openapi-
generator/projects/4)

------
asdkhadsj
Can someone describe _why_ gRPC-Web needs a proxy?

I recently had trouble deciding between the official gRPC-Web and Improbable's
gRPC-Web[1]. In the end I decided on Improbable's, because it seemed to not
require a proxy. In practice, it's working very nicely.

Yet, I'm still not clear on what exactly the Proxy serves to do, in either
case. If a browser supports HTTP 2, why is a proxy needed?

[1]: [https://github.com/improbable-eng/grpc-
web](https://github.com/improbable-eng/grpc-web)

~~~
hsaliak
gRPC needs access HTTP/2 trailers, which is not supported in browsers today.
This necessitates translation in a proxy of some form. It is possible to
support in-process or local proxies, but instead starting with this in n
languages, we are starting with a proxy, with the intention to build in-
process support on languages or use cases where there is real need for it.

~~~
thwd
Note that trailers have existed since HTTP 1.1.

~~~
chrissnell
The answer--as I recall--from the Chromium team was that they see trailers
access as a security issue. HTTP/2 multiplexes many connections and it was a
security risk, they said, to allow one client process to access trailers for
connections that may be used by different processes or even entirely different
sites behind the same load balancer/reverse proxy/etc.

What I don't understand is _why_ gRPC was designed to depend on trailers. Web
gRPC is the killer app for this technology. If they could build a new version
of the protocol that doesn't rely on trailers, I would be thrilled.

~~~
mentat
I believe trailers are because you could start streaming a response and end up
having an error than you need to communicate out of band. Hopefully someone
has a better answer though.

~~~
aktau
I've been trying to read the HTTP2 spec and I can't figure out whether it's
allowable to return or modify the HTTP(2) status code in a trailer instead of
in the header.

After some re-readings, I decided it wasn't allowed.

But then, gRPC definitely needs to be able to signal an error even after it
has already streamed data. So gRPC would need to use some end-of-connection
message, like a trailer.

------
bcheung
Can people share their experience and success stories with gRPC and/or
GraphQL?

I've tried both in the past and found that APIs are rarely as static as typed
API systems require. Many APIs have fields that are required conditionally
based on the value of other fields. Other times the schema is dynamic and
workarounds are required like stuffing things into a JSON object and making it
a "string" in the API. This added a bunch of work to marshall it in and out of
a custom workaround format.

In both cases (gRPC and GraphQL) we've run into so many issues that the
technology was abandoned and we fell back to plain JSON REST.

~~~
yashap
Have used both, and don’t like either. I actually DO like very statically
typed schemas, but you can easily do this with json over REST, and using IDLs
to generate SDKs.

For gRPC vs. REST, I just don’t see the benefits. Performance wins of gRPC are
extremely minimal for most backends, ”push based” workflows can easily be
handled with webhooks (or message queues), so why am I throwing out extremely
mature technology (and tooling/middleware!) that every dev is very familiar
with?

For GraphQL, reducing client/datacentre round trips is nice, but can also
easily be achieved with RESTful “coordination” services, that serve the front
end specifically, and do nothing but stringing together calls to backend
services. Why force people to learn another complex technology for that?
“Returning smaller payloads” makes minimal impact in practice, and GraphQL
requests are MASSIVE compared to REST requests, so you often end up with a
performance loss, not gain. Also, GraphQL requests are way harder to glance at
in the browser, you can’t just look for GET /dog/123, you have to peek into
all the request bodies. And again, all the great REST middleware stops
working, because you’re doing RPC.

Basically I see them both as extra complexity with little payoff.

~~~
cheapsteak
Curious to know if you would count "ecosystem" as a point towards either?
Afaik there isn't a standardized way of creating statically typed schemas for
REST. A standard statically typed schema like GraphQL's allows a community to
create and maintain tooling around it. A person would create"[some tool] for
GraphQL" instead of "[some tool] for [specific api]"

~~~
bcheung
In theory, yes, but in the case of GraphQL, I found it was very difficult to
generate schemas dynamically. Factoring out common fields was not possible.
Common fields in schemas had to be duplicated and there was no concept of an
include/mixin/extends/etc. Best technique was generating plaintext strings of
GraphQL programmatically (losing any editor or type checking support).
Dropping down to the AST layer of GraphQL is a bit more programmatic but not
really an ideal level of abstraction to work at. It was too verbose and low
level.

REST integrates well with native JS constructs (it's just data) so it's much
easier to compose and use metaprogramming techniques.

------
rcfox
What does GA mean? The article uses it a few times but doesn't define it.

~~~
azurezyq
I think it may be aligned with GCP terms here:
[https://cloud.google.com/terms/launch-
stages](https://cloud.google.com/terms/launch-stages)

General Availability (GA) GA features are open to all developers and are
considered stable and fully qualified for production use.

~~~
hsaliak
I've taken your phrasing and addressed OP's question in the blog. Thank you.
:)

------
pkieltyka
I prefer twirp's model of no http2 requirement and supports JSON.
[https://github.com/twitchtv/twirp](https://github.com/twitchtv/twirp)

I do think twirp code could be refactored and made a lot better though.

~~~
stock_toaster
If twirp had more existing backend implementations, I would certainly use it
for more things.

~~~
zbentley
Check out Thrift: [https://thrift.apache.org/](https://thrift.apache.org/)

------
juancampa
Anyone willing to share experiences using gRPC-Web vs. GraphQL?

~~~
andy_ppp
gRPC is lightweight, highly performant, difficult to debug, difficult to
detect breaking schema changes, lots of magic going on to learn compared to
REST or GraphQL.

GraphQL is much heavier, easier to test and debug and has some performance
optimisations like data loader and is better for multiple clients to consume.
I’d say it’s easier to manage schema changes but it’s probably not empirical.
I guess huge overheads by comparison to gRPC but I’m guessing data over the
wire is a much larger piece of the pie.

Personally think GraphQL is far superior for web clients and I think gRPC for
services in general can be a pretty large overhead for most teams... at least
initially you are going to get things done much faster with restful services.

~~~
anentropic
as someone without experience in gRPC but interested to use it, I am curious
why it was difficult to detect breaking schema changes?

thanks

~~~
andy_ppp
Because the schema is based on a numbered position rather than a field name.
This means you need to never rename positions - if you want to deprecate
fields you just loose the numbering. Numbers 0-15 use less space in the
message than others for example.

------
gigatexal
This is all well and good but examples only ever show localhost quick
projects. I’d like to see the demo game upped a bit to include some basic auth
and HTTPS stuff

~~~
stan394
There is a gRPC-Web on Kubernetes example here:
[https://github.com/salrashid123/grpc_web_with_gke](https://github.com/salrashid123/grpc_web_with_gke)

------
linkmotif
I think GraphQL makes more sense here, at least in terms of unifying backend
services and presenting them to a user—aka an API gateway—but this could be a
very useful way to transmit GraphQL queries and subscriptions and for sidecar
services like authentication, or just very simple services.

------
gregwebs
I am using the HTTP Gateway and generating OpenAPI from that for type-safe
access [1]. The downside is that this introduces an additional build step in
your project.

The upside is supporting a JSON API and not requiring gPRC(-Web) for clients.
Even for non-browser clients, GRPC tooling can still be a little heavy-weight
to pull into your project compared to OpenAPI. On the other hand, not all
languages have good OpenAPI integration.

But its also quite possible to use both.

[1] [https://github.com/gogo/grpc-example](https://github.com/gogo/grpc-
example)

------
skybrian
I thought this was interesting from the roadmap:

"The binary protobuf encoding format is not most CPU efficient for browser
clients. Furthermore, the generated code size increases as the total protobuf
definition increases.

"For Google's Web applications (e.g. gmail), we use a JSON like format which
is comparable to JSON in efficiency but also very compact in both the message
size and code size."

I wonder what the benchmarks look like? It seems surprising this hasn't
changed with newer browser optimizations.

~~~
romed
Proto encoding makes the unfortunate choice of more-bit variable-length
numbers which are hard to decode. JavaScript engines and browser all have very
well optimized decoders for the unary length-prefixed variable-length numbers
(i.e. UTF-8). So you can imagine how an encoding very much like proto but with
the proper style of varints can be faster.

Generated code size is a huge problem of all protobuf-supporting languages,
not just js. Code size issues on Android have constrained development of the
official (google) protobuf libraries in various ways over the years.

------
victor106
Anyone here knows if gRPC-Web provides performance benefits as opposed to
using REST?

~~~
larkost
RethinkDB switched away from Protobufs (which underly GRPC) in favor of JSON
when talking with both Python and Ruby clients because it was so much slower
than using JSON. My guess is that this is still true, and even worse for
JavaScript (that last is pure speculation). But I would be happy to see real
benchmarks done now.

~~~
puzzle
Python protocol buffers can use either a native or a C++ implementation. The
latter is more than an order of magnitude faster. I'm wondering if they tried
that. It doesn't solve the Ruby case, of course. Or JavaScript. gRPC can also
use Flatbuffers, by the way.

------
polskibus
What's the advantage of gRPC-Web to someone in the .NET world that uses
Typescript, and generates TS schemas from .NET POCOs ?

~~~
zbentley
Protobufs (the transfer format of gRPC) include not just a schema, but a
transport format that may be more efficient than a serialized POCO.

gRPC also allows you to encode communication semantics (i.e. "What does this
endpoint want as arguments? What does it return?") and generate both client
and server code that complies with (and automatically [de]serializes and
validates protobuf data for) those semantics.

It's the difference between a schema definition and a schema definition +
serialization format + _service_ (not just data) definition/codegen.

------
z3t4
Has anyone gone from plain text JSON to protobuffer (over Websocket) ? How
much bandwidth did you save, and was it worth it ?

------
ilaksh
How does this compare to JSON-rpc or GraphQL or just using JSON to send custom
messages over HTTP 1.1 or HTTP 2?

------
JBReefer
Isn't this just WCF reborn? Contracts, codegen no one will use, etc

~~~
zbentley
Awww, man. I _like_ WCF; wish more people would use it (and use it right).

So much of the stuff I've had to do there is untangling the work of people
that fundamentally don't want what WCF provides (quick, one-size-fits-all-
imperfectly prototyping with an option for greater flexibility later on), and
instead want 'automatic contract enforcement, but I still get to write the
client/server code from scratch the way I used to', which is a recipe for
sadness.

------
Myrth
[https://xkcd.com/927/](https://xkcd.com/927/)

------
nprateem
Thus ends REST.

~~~
Myrth
Cue the relevant xkcd standards comic.

------
brad0
Personally I don't think that gRPC is a good step forward.

However, if the community at large moves away from REST + JSON to gRPC I'll
follow.

Why?

\- I don't want to be like the guy who refuses to use anything but XML + SOAP

\- I want to be valuable on the job market. Putting gRPC may get you in the
door

\- Avoid bikeshedding

Anyone who's been in the industry a few years knows that "the way" to do
things changes often. Going with the flow and completing the actual job is
what matters.

~~~
ljm
I found gRPC to be exciting when I was writing something in Go. The tooling
around that is pretty decent and it sets a certain expectation about how it
works.

Then I had to write a client in a different language, and the generated code
was utterly intuitive. gRPC itself adds extensions to Protobuf to handle code-
gen nuances but of course they're deployed in Go-land, not relevant-language-
land.

That's a small niggle that's easily solved one way or another. What was
frustrating was that the `protobuf` CLI could handle language extensions, but
you couldn't make use of that without a hell of a lot of faff. If you want to
add a gRPC client to your Rails app you can't use the protobuf CLI, that you
might already have.... you have to add a gem that includes a different version
of the protobuf CLI that is guaranteed to be not compatible. Even the command
and its args aren't compatible.

When I found myself working against that I just gave up. It's a solution that
sounds elegant, but you're going to get a feature out of the door much quicker
if you steer away from that layer altogether. There's nothing wrong with an
ad-hoc HTTP API if you're confident about the interface.

Technical purity isn't technical excellence and nor is it user value. Just
like K8S, you're not gonna need RPC on the web unless you can justify the
scale and have the firepower to handle it.

------
calebh
I think that if we're going to have a full blown typed RPC system, we need to
at least be able to represent generics/parametric polymorphism. As far as I
know, protobufs do not support this feature! Why are we settling for using a
subpar interchange format when the alternative (polymorphic sum types) is so
much better?

~~~
superfrank
Can you give me an example where generics would be helpful? I'm not doubting
you, my brain is just a little slow today and I'm struggling to think of a
scenario where I feel I would NEED them for gRPC.

~~~
deathanatos
Option<T>.

Protobuf "supports" this particular case via other means: messages are always
implicitly nullable, and the WKTs cover primitives, which don't count as
messages.

Map<K, V>: Protobuf has dedicated syntax for this case.

------
lost-theory
It's interesting to watch Google's moves to control every part of the stack.
Browser: Chrome. Frontend: Closure compiler -> obfuscated SPAs. Transport:
gRPC. Backend: Proprietary Google software written in Golang. Orchestration:
Kubernetes. Hosting: Google Cloud. Etc. You can imagine a future where Google
services are no longer just web apps on the same footing as anything else in
the web ecosystem, but where every step of the development, deployment, and
end-use is managed by Google. Can't blame them for doing that, I'm sure it's
more efficient, but it's definitely moving the web in a different direction,
one where Google has more control at the expense of everyone else (end users,
competitors).

~~~
atombender
They're not controlling anything by releasing open-source libraries/languages
such as gRPC, Kubernetes and Go. Releasing these things don't give them
control over anything that can negatively impact users; this is not
Microsoft's embrace-and-extend.

Chrome, on the other hand, is worth worrying about. Unlike the other
technologies you mention, it's a consumer application that legitimately lets
Google apply Microsoft-style embrace-and-extend tactics, monopolizing the web
and steering it in a direction that benefits Google more than anything (e.g.
ads and tracking).

Kubernetes may have come out of Google, but it isn't even in their control
anymore. If anything, Kubernetes is a strategic play to democratize cloud
orchestration, undermining competitors such as AWS.

~~~
lost-theory
Good points. I don't see anything wrong with these individual open source
releases. See my other comments about the larger trend this represents.

"Releasing these things don't give them control over anything that negatively
impacts users" and "undermining competitors such as AWS" contradict with each
other if you believe competition is good for users. The decision to release
something as open source doesn't happen in a vacuum. Open source doesn't
automatically make corporate activity morally good or neutral.

------
mlthoughts2018
This is going to enable so many people to find-replace “Thrift” with “gRPC”
for such an easy solution to updating legacy Slack messages, GitHub issues,
and message board threads.

Updating your outrage at a stupid tool nobody should use has never been
easier!

