
Announcing gRPC Support in Nginx - tex0
https://www.nginx.com/blog/nginx-1-13-10-grpc/
======
anameaname
Finally! Up until now, when people ask how they are supposed to proxy grpc
traffic, we could only recommend Envoy. Pretty much no one wants to hear that
they have to change their stack to use new technology. Since a large part of
the world is already on nginx, this was a a real barrier for adoption.

Next up, browser support?

~~~
pacala
> Next up, browser support?

Please! There is a working TypeScript client implementation [0] of gRPC-Web
[1], which relies on a custom proxy for converting gRPC to gRPC-Web [2]. Would
be nice to bring that proxy functionality into Nginx.

[0] [https://github.com/improbable-eng/grpc-
web/tree/master/ts](https://github.com/improbable-eng/grpc-web/tree/master/ts)

[1] [https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-
WEB.md](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md)

[2] [https://github.com/improbable-eng/grpc-
web/tree/master/go/gr...](https://github.com/improbable-eng/grpc-
web/tree/master/go/grpcwebproxy)

~~~
pieterlouw
Caddy Web Server ([https://caddyserver.com](https://caddyserver.com)) have
support for gRPC-Web through it's grpc plugin:
[https://caddyserver.com/docs/http.grpc](https://caddyserver.com/docs/http.grpc)

------
Matthias247
If gRPC would have been designed slightly different, they could have had good
proxy support AND browser support right from the start.

E.g. it's already based on top of HTTP(/2), and uses normal path for
distinguishing methods, which would actually be a good prerequisite to make it
work everywhere. But then OTOH it uses barely support HTTP features like
trailers, which require very special HTTP libraries and are not universally
supported. If the status codes there would have been implemented as just
another chunk of the HTTP body, and if some other small changes had been done,
we could have had gprc from browsers already a long time ago. I guess that's
what grpc-web now tries to fix, but I haven't dug into that in detail.

~~~
anameaname
For the record, the reason grpc uses trailers is because it uses http/2, not
the other way around. It was expected that since the whole transport was
completely new, adopters of http/2 would add trailer support. As it turns out,
they mostly didn't. Particularly Firefox and Chrome did not expose trailers.
This is even despite being part of the new Fetch API.

------
x25519
Code

Initial commit:
[https://hg.nginx.org/nginx/rev/2713b2dbf5bb](https://hg.nginx.org/nginx/rev/2713b2dbf5bb)

Additional features:
[https://hg.nginx.org/nginx/rev/c693daca57f7](https://hg.nginx.org/nginx/rev/c693daca57f7)
and
[https://hg.nginx.org/nginx/rev/c2a0a838c40f](https://hg.nginx.org/nginx/rev/c2a0a838c40f)

~~~
nginxgrpc
Wow, I was surprised at the sheer size of the diff. Huge!

Can any of you tell if it includes unit tests? I didn't see any.

~~~
an_account_name
Their tests live in a separate repo

~~~
philipwhiuk
That must make working out whether a code change is well tested a whole bunch
of fun.

------
andrewstuart
OK so what are good use cases for gRPC? What problem does it solve, and in
what contexts should I be reaching for gRPC?

~~~
ericjang
I used gRPC for numerous hobby projects during my undergrad to glue together
binaries running in different languages (e.g. a simulation server running in
C++ and a scripting client in Python). By passing around a shared data
structure (Protobufs), one does not need to waste time writing
serialization/de-serialization adapters. It is also useful for gluing together
microservices.

FB's Thrift also solves the same problem, and is an alternative to gRPC.

~~~
rejectedalot
Going into the microservice aspect above, it provides a nice abstraction of
remote function calls, so that you can write microservice code that looks like
it's executing a local function, but is really just expecting a remote server
to implement the method name. In general, that's just RPC calls though.
Google's implementation has proven very intuitive to learn, and has a nice
size community online for help debugging, etc.

------
toprerules
I love seeing grpc grow. An rpc system with a schema and code generation is a
must for internal services. Grpc has worked really well for me.

~~~
adamkl
No disrespect intended, but I find this comment pretty funny. SOAP/XML has
been exactly this for 20 years. It definitely has some major warts, but gRPC
isn’t doing anything new.

~~~
StevePerkins
And CORBA/IDL was doing exactly the same 20 years prior to that.

We get tired of things because they accumulate cruft, or are deemed "ugly" by
younger developers. So we replace them with newer alternatives, that are more
light and easy to reason about for newbies entering the profession. But then
we eventually find that we needed more features after all, so we gradually re-
implement them again until the cycle repeats. The industry wheel just keeps on
spinning...

~~~
haberman
I think this is a bit of an oversimplification. The modern approach to RPC is
very different than CORBA or even SOAP/XML.

CORBA was designed around the idea of distributed objects. The core idea was
that you have a reference to an object but you don't know (or care) if the
object lives in your address space or on a remote computer somewhere. When you
make a "remote procedure call", CORBA tries to make it behave as if it were
just a regular function call. The call would block the thread until it
completed, and any communication errors would be marshaled into some kind of
language exception.

It turns out that RPCs are different from regular function calls in a lot of
ways. Trying to make them the same just makes things overall more complicated
and less flexible. Also, making "remote objects" stateful creates a lot of
problems for little benefit.

So XML/SOAP did away with these ideas. Instead of being designed around remote
object references, it was designed around request/reply to a network endpoint.
No statefulness was designed into the protocol, though of course it could be
layered on top by enclosing your own data identifiers.

But SOAP was based around XML, which was never really designed to be a object
serialization format. Compared to alternatives like Protocol Buffers, XML is
big, slow, and not a clean mapping to the kinds of data structures you use in
programming languages. Protocol Buffers are a much better match to this
problem. (More at: [https://developers.google.com/protocol-
buffers/docs/overview...](https://developers.google.com/protocol-
buffers/docs/overview#whynotxml))

My point is that these new technologies aren't just repeats, there are real
improvements that justify inventing something new.

~~~
adamkl
I totally agree that these new technologies are an improvement, and I have no
desire to go back to SOAP/XML, I was just commenting on the statement:

    
    
      An rpc system with a schema and code generation is a must for internal services.
    

Which seemed to suggest that gRPC is somehow novel in this respect.

~~~
merb
well I would guess the difference between soap and grpc is that soap was
developed as a standard, while gRPC became one (or is becoming one).

Also the biggest difference is, that soap had like a trillion implementations
which all worked kinda differently. code generation, etc.. GRPC somewhat does
not have this problem because basically there is only one client
implementation managed by google (now the cnf).

also in soap you basically built your server first, because writing a wsdl
from scratch is like... akward. the idl of grpc is extremly simple to actually
start without any implementation at all. and as a bonus it works way better if
you need to add/change fields.

------
perfmode
Seems they punted on graceful handling of bidirectional streams.

~~~
whyrusleeping
last i checked grpc could only technically support bidirectional streams. None
of the libraries I looked at actually implemented it.

~~~
maltalex
> None of the libraries I looked at actually implemented it.

Can you elaborate on that?

AFAIK gRPC comes with bidirectional streams out of the box. I played around
with gRPC on Java and it seemed to work.

~~~
jimmy1
Go user checking in here as well -- bidirectional streams work just fine

------
awinder
Does this mean anything for http2, specifically anything for support for http2
upstreams? I would imagine that’s was a necessity to support for grpc so any
way that will come to generic http2 as well?

------
chuckdries
Anyone have a good ELI5 of gRPC? It says it's a fast RPC implementation, but
all the explanations of RPC seem very in-the-weeds.

~~~
adrianmonk
Not sure if you're looking for an explanation of RPC in general or just
specifically how gRPC does it, but I guess I'll kind of cover both.

You define a series of set method calls, using a custom language. Each method
call has a single message as its request and another message as its response.
(You can actually get fancier than this, but you usually don't.)

In gRPC, the messages are usually protocol buffers (though other formats are
supported like JSON). The method calls are organized into groups called
services.

You stick these definitions in a file, then run a tool that takes these
definitions and generates code in your desired language (Java, Python, etc. --
gRPC supports many languages). This code allows you to build objects that will
get turned into protocol buffers wire format and sent across from client to
server and back.

So for example, if you define a method Foo that takes a FooRequest and returns
a FooResponse, you would put this a definition file, run a tool that generates
some code. For the sake of this example, we'll say you're using Java for
everything, so you tell the tool to generate Java code. This generated Java
code would include code to create a FooRequest object, set values in it
(strings, ints, etc.). It would also include a Java method you can call that
takes your FooRequest and sends it to the server and that gives you back a
FooResponse after the server responds. On the server side, you also get Java
code that is generated to help you respond to this request. Your Java code on
the server side will receive a FooRequest, and it can use generated Java code
to read the fields out of it (those same strings, ints, etc.), and then it can
build a response in the same way that the client built the request.

On the client, there is obviously some work involved in opening connections to
the server, converting the FooRequest into wire-format data (and vice versa
for FooResponse), but that is done for you, and you just need to tell it the
server's address. On the server, there is work involved in listening for
connections from clients, figuring out which RPC method is being called and
routing it to the right Java method, converting the wire-format data into
objects (and vice versa), but all that is done for you, and you just need to
tell it what port to listen on.

gRPC itself uses HTTP/2 and makes POST calls when your client calls a method.
The methods and services you define are mapped to URLs. So if you define a Bar
service with a Foo method inside, it will be turned into /Bar/Foo when the
HTTP call is made.

~~~
adrianmonk
In case it was confusing, I meant to type "set of method calls" in my comment
above, not "series of set method calls".

(I'd edit the comment but it's too late.)

------
grizzles
This is great; I also recently published an alternative designed for browser
clients:
[https://github.com/ericbets/danby](https://github.com/ericbets/danby)

It's designed to be very simple to configure. It doesn't support streams yet,
but it should soon.

------
brunosutic
This is great! TL;DR: instead of building JSON or GraphQL API now you can
easily expose your gRPC service to the outside world!

We use gRPC in my company. We're happy but some things were not easy or
straightforward to implement. With this update nginx makes load balancing and
authentication easier to implement.

~~~
tango12
I was actually just about to say that. There seems to be fair bit of overlap
in graphql and grpc from the Codegen and Schema POV. Graphql is more intended
to be a data query language and grpc more generic function calls.

But they’re both essentially solving the dev problem of having ‘typed
contracts’ right?

Very interesting evolution! SOAP to REST to graphql more popular on the
‘frontend’ side and grpc on the ‘backend’ side.

------
sigmonsays
haproxy has had http/2 supports beginning 1.6 ( May 2015) however I have not
yet looked into using it. I do wonder if it posses the same features in terms
of inspecting the method names on a per request basis.

------
wolfspider
congrats to the Nginx team and contributors! some of us have been waiting
anxiously for this release- this will be great!

------
throwawaysunday
This is not cool

There is no place for gRPC in NGINX.

This is Google trying to thin end of the wedge their own proprietary protocols
into web standards yet again.

My idea of a good time is not a future where the internet is built using
Google technologies dressed as "open technologies".. that.. uh-huh just happen
to be the exact same as infrastructure protocols that span the internal
Googleverse.

Besides that, protobuf and its ilk aren't even good or modern.

People who say, yay look at it growing are very naive imho

~~~
colordrops
Just out of curiosity, what's a modern alternative to protobufs?

~~~
throwawaysunday
One that is type extensible, not brittle and based on schemas with fragile
language integration tools, is streamable down to the atom level, naturally
sortable, homoiconic in nature and efficient to produce and consume.

Such things exist, I'm not just rattling off buzzwords.

The main thing is protocols are serious business and people, especially any of
the big five shouldn't get to own them just because it suits a business
interest.

~~~
jbreiding
It's easy to argue you are just rattling off buzzwords if you don't provide
examples.

I would also argue that not based on a schema is even more brittle as you end
up implementing validation logic and client marshalling that the schema would
allow you to just generate.

