Skip to content
This repository has been archived by the owner on Apr 16, 2020. It is now read-only.

gRPC-Web support #35

Open
8 tasks
dflemstr opened this issue Jan 13, 2018 · 14 comments
Open
8 tasks

gRPC-Web support #35

dflemstr opened this issue Jan 13, 2018 · 14 comments

Comments

@dflemstr
Copy link

I'd like to use tower with the gRPC-Web protocol.

Some use-cases that I'm thinking about in order of priority:

  • Create a server in Rust that can be used by existing gRPC-Web client implementations (e.g. from browsers/node.js and Typescript)
  • Create a client in Rust that can be compiled to WebAssembly (and interop via for example stdweb and the Webpack native wasm loader) and used in the browser.
  • Support multiplexing ordinary gRPC and gRPC-Web on the same port.
  • Nice-to-have: Support multiplexing some other web service (e.g. static file server) for requests that are not gRPC or gRPC-Web.

I'd like to discuss how to do this in a nice way. Here's what I was (maybe naïvely) thinking:

  • Create tower-grpc-web containing a struct GrpcWebService that wraps another tower::Service using http::Request and http::Response, and transparently changes the encoding on the fly. This can then be used with tower-grpc generated clients/servers directly.
  • Create support for tower+HTTP/1
  • Build some tower glue to the WhatWG fetch API
  • Create a multiplexer that can bind a single port and dispatch to different tower::Services depending on if the request is HTTP/1 or HTTP/2 and depending on headers like Content-Type.

Does this sound sane? Are there any existing components I could leverage? Is there a smarter way to do this?

@carllerche
Copy link
Member

Yeah, it sounds roughly sane. I don't know that much about the grpc-web protocol. I also am not entirely sure what the fetch API is in practice.

If you want to experiment with something, maybe try a spike in an external repo and we can go from there.

@dflemstr
Copy link
Author

Just to update this issue, I'm still working on this but am stuck fixing lower-level components such as the compiler support for wasm interacting with webpack. If anybody else is reading this issue, please ping me if you are interested in helping out!

@ghost
Copy link

ghost commented May 4, 2018

+1 from me.
I use the improbable one with golang and would jump onto a rust version in an instant.

@ghost
Copy link

ghost commented May 4, 2018

Btw the scope is sane. It's exactly what I do in golang currently.
Golangs wasm is still a bit rough around the edges, but the rust wasm is pretty solid, so it's definitely worthwhile pursuing this

@johanbrandhorst
Copy link

Just chiming in that I've thought about doing this asynchronously but that it would be cool to contribute to an existing effort. I've got a pretty good idea of how the gRPC-Web protocol works and how to use the Fetch API with it, but I'm very inexperienced with Rust. Please let me know how I can help!

@johanbrandhorst
Copy link

I don't think it's worthwhile implementing a wrapper around the Improbable grpc-web client, just write the whole thing in WASM, it's not really a large amount of logic and you can probably copy most of it from the open source client.

@lalomartins
Copy link

lalomartins commented Mar 1, 2019

I'm not sure where the talk about WASM is coming from, that's IMO out of scope — we don't need a new grpc-web client-side implementation and if we did it would have little to do with tower. As I understand it the idea here is to add support for the server side grpc-web protocol to tower, so that I can write a server in Rust with tower and that server will support both regular grpc clients and grpc-web clients.

Edit: ok, the original request does talk about both. But I think if a client-side WASM implementation is wanted at all, it should probably be a separate ticket or even a separate project.

@johanbrandhorst
Copy link

johanbrandhorst commented Mar 1, 2019

Great, thanks for the clarification. I understand the distinction. In any case @dflemstr, please reach out (@JohanBrandhorst on twitter) because I'd love to collaborate on a client implementation. The server side, again, should be fairly trivial and translatable from the Improbable gRPC-Web proxy.

@dflemstr
Copy link
Author

@johanbrandhorst I decided to spend my time on other things while waiting for the tower ecosystem to mature a bit before spending more time on this. Maybe now is a good time to continue.

What I would like to have is a detailed understanding of how to translate a gRPC-Web request to gRPC and vice versa. Right now there is only the Go reference implementation which is a bit hard to follow (it mutates request objects here and there and has an interesting way of stashing away request trailers etc).

Given that we have that, a tower wrapper should be easy to add.

I am also interested in a client implementation, that can be compiled to WASM for use client side. This enables a lot of code sharing between server and client which is quite nice.

@mash-graz
Copy link

a working implementation of gRPC-web in rust would be indeed very useful, but more satisfying support for twirp (= http1.1 protobuf+json fallback for simple browser access) in tower could be even more desirable.

@johanbrandhorst
Copy link

@mash-graz I think that could be covered under a separate issue.

@mash-graz
Copy link

@johanbrandhorst done! => #185

@micfan
Copy link

micfan commented Jun 17, 2019

I have just tested this "unofficial" grpc-web repo, it move far than the official grpc-web. The improbable-eng/grpc-web can work with Golang gRPC server.

A WSAM Rust client runing in Browser, connecting to server via HTTP2, exposing API to JS/TS... I'm frustrated, that is a huge project

@johanbrandhorst
Copy link

As mentioned in hyperium/tonic#31, I've created a sandbox repo to play around with prototyping this: https://github.com/johanbrandhorst/rust-grpc-web-wasm-test. It's currently just a Go gRPC server with the gRPC-Web proxy, the idea is that we can manually try to implement a first pass on a Rust WASM client. See the README for more information.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants