Open mitar opened 6 years ago
It will be ideal if we have something like Swagger for gRPC-Web :) I don't want to decode binary format, but I want to have some tool which let me manually enter data in human format (JSON, YAML or simply filling several textbox) and send this data to server in binary. Also I want get deserialized response from server in this tool. I think tool pregenerate message's format and service methods from proto file.
It's possible to just use JSON with gRPC. I'm not yet sure how well the various proxies handle it, but I've written about using JSON with a Go gRPC server here: https://jbrandhorst.com/post/grpc-json/. There's a also a slightly more complicated (imo) tutorial on the official grpc blog: https://grpc.io/blog/grpc-with-json.
That said, it would be nice to show an example of a gRPC-Web client using JSON as the payload encoding in an example.
This was a similar issue our Frontend teams where facing, so I put together a simple Chrome extension:
https://github.com/SafetyCulture/grpc-web-devtools/
Right now it is very basic, but has a lot of potential. Not published to the Chrome store at the moment, but should be easy enough to install locally.
As of today, it only supports Unary request via the PromiseClient
as that is what we use, but should be easy to enable callback requests and streaming.
Ideally some of this code would better sit within this repo to make intercepting the req/res and sending to the dev tools panel easier (client side interceptors would be another good option).
Keen for people to try this tool out (PRs welcome) and maybe we can merge it back to this project once it becomes a bit more stable.
I'm hoping that our Frontend teams will help me make the UI better, with more features: search, clear, pause etc. Was also thinking that a "mock" response would be a cool feature tool; allowing a Frontend Engineer develop without a backend server and proxy.
@rogchap Thanks for your work on grpc-web devtoosls. We are happy to host the chrome extension in this repo. @stanley-cheung
JSON support in grpc-web is being considered. OTOH, the protobuf javascript team is actively working on optimizing the efficiency and (generated) code size of the current protobuf JS library.
For ease of debugging, dev tools may prove to be sufficient than adding JSON support for browser clients ... and JSON will add overhead on the server-side and may also require proxy support for some languages.
@wenbozhu Thanks, thatβs great.
Just recently published the dev tools to the Chrome Web Store: https://chrome.google.com/webstore/detail/grpc-web-developer-tools/ddamlpimmiapbcopeoifjfmoabdbfbjj
Happy to move the extension to this repo; what do you propose the next steps to be?
Couple of questions:
Ok... so I've thought more about this (after a nights sleep) and I have an idea on how this could play out:
Let me know what you think @wenbozhu @stanley-cheung
The extension today uses a content_script.js
to inject some code that the web page (the client implementation) so that we can override the rpcCall
and unaryCall
calls (not done streaming yet).
This provides the API to expose the grpc client to the Devtools via:
const enableDevTools = window.__GRPCWEB_DEVTOOLS__ || (() => {});
const client = new EchoServiceClient('http://myapi.com');
enableDevTools([
client,
]);
Although this works, any changes to the rpcCall
and unaryCall
in gRPC-Web would mean updating in the extension too, which is not ideal. Ideally we would have the Devtools messaging calls within the gRPC-Web javascript package within rpcCall
itself; this means that we would not need to do some crazy overriding of the methods.
The main body of this message is this:
window.postMessage({
type: "__GRPCWEB_DEVTOOLS__",
method,
request: request.toObject(),
response: err ? null : response.toObject(),
error: err,
}, "*");
By having this code directly within this project would mean the extension would not need to inject any code to the web page, and the developer would not need to pass their gRPC client through an enableDevTools
function.
That said, developers will still want to enable/disable DevTools tracking, so I would propose a client option to turn this on/off. eg:
const client = new ExampleClient('http://0.0.0.0:8080', null, { enableDevTools: !!__DEV__ });
With the above step implemented the current chrome extension will work and display the network messages as it does today.
This can now be implemented independently of step 1, as a second (or group) of PRs.
The main state management is redux
with a react
UI, however this is easy to change if we prefer to use another technology. All the extension messaging code can stay the same.
At some point we can then publish the new extension and I can remove/redirect to the "official" version.
@rogchap Thanks for the great work here! This is looking exciting.
So looks like there is a bit of gray area / overlap between this and a proper Interceptor API.
In my mind, devtools / browser extension should be transparent to the core library. If we have to update the core library / API, I'd prefer it to be for the purpose of introducing the Interceptor API. So I am a bit reluctant to introduce API to the client constructor you mentioned like this:
const client = new ExampleClient('http://0.0.0.0:8080', null, { enableDevTools: !!__DEV__ });
I think the intention was good, but at the API level it's debatable. I'd like to see other users chime in as well, if any of you from the community has an opinion on this.
I think that, if the extension is transparent to the core library, having the extension tied to the API (meaning that if we update the core API, the extension has to chanage), is OK. So what you proposed here:
const enableDevTools = window.__GRPCWEB_DEVTOOLS__ || (() => {});
const client = new EchoServiceClient('http://myapi.com');
enableDevTools([
client,
]);
looks OK to me. As in, the above is saying, I am writing some additional code that wraps the existing public gRPC-Web client object, and do some stuff with it for the browser extension UI purposes. For that purposes, yes this gets tied when rpcCall
and/or unaryCall
signature changed, which itself is an unlikely event.
Again, thank you very much for taking this on. We should keep the dialog open.
Funny you should mention interceptors as this was what I looked for when I first started putting this together! I even commented on the issue to see if we could get the proposal aligned: https://github.com/grpc/grpc-web/issues/283#issuecomment-483074550
Happy to keep the current API the same and provide the whole thing in one PR. Do you have any feedback on the UI part (specifically it using React & Redux) @stanley-cheung?
In terms of next steps, I want to get the extension displaying streaming requests/responses and highlight them vs unary calls (currently only unary is supported); I'll do this in my current project. Once this is done I can provide time to port to this project with any changes.
Alternatively I can put this on hold, and provide time to help with the Interceptor work, and come back to this once that is merged. π
Maybe something like Charles Protobuf Text
will be OK?
https://www.charlesproxy.com/documentation/using-charles/protocol-buffers/#text_viewer
// No message type specified.
1: 0
3: 0
4: "..."
5 {
1: 0
2: "..."
3: 0
4 {
1: 0
2: "..."
3 {
1: "..."
2: "..."
3: 1
}
4 {
1: "..."
2: "..."
3: 2
}
5 {
1: "..."
2: "..."
3: 3
}
}
5: "..."
11: 0
}
Hello everyone π
I published a chrome extension to debug gRPC-web activity: https://chromewebstore.google.com/detail/grpc-devtools-for-grpc-we/fohdnlaeecihjiendkfhifhlgldpeopm
It uses a Network Panel-like UI and is made using the interceptor API.
Hope it helps. π
@iendeavor Thanks for your contribution! Very cool!π
I think it would be very useful to be able to debug grpc messages in the web console, in the network tab.