Coder Social home page Coder Social logo

fullstorydev / grpcui Goto Github PK

View Code? Open in Web Editor NEW
4.9K 54.0 370.0 8.62 MB

An interactive web UI for gRPC, along the lines of postman

License: MIT License

Go 44.76% Shell 1.25% HTML 3.24% CSS 5.76% JavaScript 43.48% Makefile 1.08% Dockerfile 0.42%
grpc postman golang

grpcui's Introduction

gRPC UI

Build Status Go Report Card

grpcui is a command-line tool that lets you interact with gRPC servers via a browser. It's sort of like Postman, but for gRPC APIs instead of REST.

In some ways, this is like an extension to grpcurl. Whereas grpcurl is a command-line interface, grpcui provides a web/browser-based GUI. This lets you interactively construct requests to send to a gRPC server.

With this tool you can also browse the schema for gRPC services, which is presented as a list of available endpoints. This is enabled either by querying a server that supports server reflection, by reading proto source files, or by loading in compiled "protoset" files (files that contain encoded file descriptor protos). In fact, the way the tool transforms JSON request data into a binary encoded protobuf is using that very same schema. So, if the server you interact with does not support reflection, you will either need the proto source files that define the service or need protoset files that grpcui can use.

This repo also provides two library packages

  1. github.com/fullstorydev/grpcui: This package contains the building blocks for embedding a gRPC web form into any Go HTTP server. It has functions for accessing the HTML form, the JavaScript code that powers it, as well as a sample CSS file, for styling the form.
  2. github.com/fullstorydev/grpcui/standalone: This package goes a step further and supplies a single, simple HTTP handler that provides the entire gRPC web UI. You can just wire this handler into your HTTP server to embed a gRPC web page that looks exactly like the one you see when you use the grpcui command-line program. This single handler uses the above package but also supplies the enclosing HTML page, some other script dependencies (jQuery and jQuery-UI), and additional CSS and image resources.

Features

grpcui supports all kinds of RPC methods, including streaming methods. However, it requires you to construct the entire stream of request messages all at once and then renders the entire resulting stream of response messages all at once (so you can't interact with bidirectional streams the way that grpcurl can).

grpcui supports both plain-text and TLS servers and has numerous options for TLS configuration. It also supports mutual TLS, where the client is required to present a client certificate.

As mentioned above, grpcui works seamlessly if the server supports the reflection service. If not, you can supply the .proto source files or you can supply protoset files (containing compiled descriptors, produced by protoc) to grpcui.

The web UI allows you to set request metadata in addition to defining the request message data. When defining request message data, it uses a dynamic HTML form that supports data entry for all possible kinds of protobuf messages, including rich support for well-known types (such as google.protobuf.Timestamp), one ofs, and maps.

In addition to entering the data via HTML form, you can also enter the data in JSON format, by typing or pasting the entire JSON request body into a text form.

Upon issuing an RPC, the web UI shows all gRPC response metadata, including both headers and trailers sent by the server. And, of course, it shows a human-comprehensible response body, in the form of an HTML table.

Installation

Homebrew (MacOS or Linux)

Install with homebrew:

brew install grpcui

From Source

You can use the go tool to install grpcui:

go install github.com/fullstorydev/grpcui/cmd/grpcui@latest

This installs the command into the bin sub-folder of wherever your $GOPATH environment variable points. If this directory is already in your $PATH, then you should be good to go.

If you have already pulled down this repo to a location that is not in your $GOPATH and want to build from the sources, you can cd into the repo and then run make install.

If you encounter compile errors, you could have out-dated versions of grpcui's dependencies. You can update the dependencies by running make updatedeps.

Running without install

go run ./cmd/grpcui/grpcui.go -plaintext localhost:9019

Usage

The usage doc for the tool explains the numerous options:

grpcui -help

Most of the flags control how the program connects to the gRPC server that to which requests will be sent. However, there is one flag that controls grpcui itself: the -port flag controls what port the HTTP server should use to expose the web UI. If no port is specified, an ephemeral port will be used (so likely a different port each time it is run, allocated by the operating system).

Web Form

When you run grpcui, it will show you a URL to put into a browser in order to access the web UI.

$ grpcui -plaintext localhost:12345
gRPC Web UI available at http://127.0.0.1:60551/...

When you navigate to this URL, you are presented with the user interface:

web UI screenshots

The top two listboxes allow you to select the service and method of the RPC to issue. Once a selection is made, the panel below will show a form that allows you to define an RPC request. The form is constructed, dynamically, based on the actual request message structure of the selected RPC.

You'll notice a second tab that lets you view (and edit) the raw JSON value for the request data. This can be useful to copy+paste a large request message, without having to point-and-click to define each field value, one at a time.

The third tab shows the response data. This tab is grayed out and disabled until you actually click the "Invoke" button, which can be found at the bottom of the page.

Request Form

The first thing to note about the form is that it will generally be a table, where each row is a field. The table has three important columns:

  1. The first column shows the name and type of the field.
  2. The second columns indicates the "cardinality" of the field. Typical fields are optional. The second column for optional fields is a checkbox indicating whether the field is present or not. If the field is not present, its default value is assumed. Repeated fields show buttons in this column for adding and deletig values. The green "+" allows you to add values to the repeated field. The red "x" next to a value will remove that value. Finally, if the field is required (only supported in syntax "proto2"), the column will contain only an asterisk.
  3. The third column shows the value of the field. If the field is absent, this will show the default value for the field. Fields that are nested messages show "unset", but scalar types show their default (usually the type's zero value, but default values are configurable when using syntax "proto2"). Absent fields are also not editable -- you must first check the box in column two to make the field present before editing its value. Repeated fields show a nested table that occupies columns two and three and allows for adding and removing values.

Fields whose type is a nested message will include a nested table in column three. This nested table has its own three columns and one row per field therein.

One-ofs are rendered a little differently. Instead of two columns indicating the presence and value of the field, they include a nested table showing all of the possible fields in the one-of. However, the middle column is a radio button instead of a checkbox, so that only one of the fields can be present at any given time. In addition to a row for each field in the one-of, there is also an option named None, which indicates a one-of where no value is set.

Here's an example form for a message that has two required fields (id and name), one repeated field (labels), a handful of normal optional fields, and a single one-of that has four options. In the first image, no values are present (except, of course, for the required fields at the top). In the second, several field values are present.

web UI message fields web UI message fields, with some values

For RPCs that accept a stream of requests, the web form allows the user to define multiple messages in the stream. It defaults to a single request, but the user can remove it to send none or can send many. A stream resembles a repeated field, but the repeated "thing" is the entire request:

web UI request stream

That last example also shows how well-known message types get special treatment. In that example, the request type is google.protobuf.StringValue. Instead of showing a form for a message with a single field named value with type string, the UI is simple and the "boxing" ceremony is elided. It instead just shows a simple textbox for entering the string value.

A more interesting example of how well-known message types are treated is google.protobuf.Timestamp, where a date picker is shown:

web UI request stream

Raw Request JSON

The second tab lets you view the JSON representation of the request data you have defined on the first tab. You can also directly edit the JSON data -- including pasting in an entire JSON message.

The JSON representation uses the standard JSON mapping for Protocol Buffers.

web UI request JSON

When working with an RPC that has a streaming request, the JSON data will be a JSON array, where each element is a single message in the stream.

Responses

When the "Invoke" button is pressed, the request data is sent to the server and the selected RPC method is invoked. The web form will then navigate to the third tab to show the server's response.

The response tab has three sections:

  1. Response Headers: Any response header metadata is shown here.
  2. Response Data: Any response messages are shown here as are any error messages. RPC methods with a streaming response may show both message data and an error. Error messages show the gRPC status code and the server-defined message text.
  3. Response Trailers: Finally, any response trailer metadata is shown.

web UI response

Each of these three sections is a table of data. Response messages are the most interesting, and their structure closely resembles how messages are structured on the "Request Form" tab. Fields that have nested messages will include a nested table.

Descriptor Sources

The grpcui tool can operate on a variety of sources for descriptors. The descriptors are required, in order for grpcui to understand the RPC schema, translate inputs into the protobuf binary format as well as translate responses from the binary format into text. The sections below document the supported sources and what command-line flags are needed to use them.

Server Reflection

Without any additional command-line flags, grpcui will try to use server reflection.

Examples for how to set up server reflection can be found here.

Proto Source Files

To use grpcui on servers that do not support reflection, you can use .proto source files.

In addition to using -proto flags to point grpcui at the relevant proto source file(s), you may also need to supply -import-path flags to tell grpcui the folders from which dependencies can be imported.

Just like when compiling with protoc, you do not need to provide an import path for the location of the standard protos included with protoc (which contain various "well-known types" with a package definition of google.protobuf). These files are "known" by grpcui as a snapshot of their descriptors is built into the grpcui binary.

Protoset Files

You can also use compiled protoset files with grpcui. Protoset files contain binary encoded google.protobuf.FileDescriptorSet protos. To create a protoset file, invoke protoc with the *.proto files that define the service:

protoc --proto_path=. \
    --descriptor_set_out=myservice.protoset \
    --include_imports \
    my/custom/server/service.proto

The --descriptor_set_out argument is what tells protoc to produce a protoset, and the --include_imports argument is necessary for the protoset to contain everything that grpcui needs to process and understand the schema.

grpcui's People

Contributors

2yuri avatar colega avatar dependabot[bot] avatar dragonsinth avatar gerektoolhy avatar gpassini avatar gtg471h avatar gubtos avatar hojongs avatar ismaildawoodjee avatar james-bartman avatar jerome-quere avatar jhump avatar johanbrandhorst avatar jtsai-dev avatar kohenkatz avatar lemmerelassal avatar maximus1108 avatar rokostik avatar sanjaybv avatar termie avatar thejenix avatar thempatel avatar wolfogre avatar xwjdsh avatar y-yagi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grpcui's Issues

Support for google.protobuf.FieldMask well known type

Consider supporting FieldMask in a more advanced way by allowing you to select the properties of a message that should be included.

Some nice to have options and things to consider:

  1. Flatten the paths property to be top level instead of having it nest
  2. The ability to switch back to the string[] approach for any edge cases
  3. The ability to specify which message/property the fields are relative to
  4. Maybe a set from request button that creates a FieldMask paths from all the included fields you've already filled out in your request

Example
My API has a pattern where resource update methods look like UpdateFoo(UpdateFooRequest).

message UpdateFooRequest {
  Foo foo = 1;
  // fields relative to foo
  google.protobuf.FieldMask update_mask = 2;
  // ... other update metadata
}

Which allows for updating specific fields in the resource (Foo in this case), I thought more advanced support for FieldMask would help out.

Specify headers to use regardless of reflection

As the docs say, -reflect-headers are only used for reflection requests:

These headers will only be used during reflection requests

Is there a way to pass headers that get used regardless?

unable to send empty strings

I have a service where a certain field is a string and can be empty.

If I send a request through grpcui using an empty string, my grpc service does not receive that field at all.

I'd expect to see a difference between:

  • field checkbox enabled in grpui but field empty: my grpc service should receive empty value for that field
    image

vs

  • field checkbox not enbled in grpui: my grpc service should not receive such field

image

in my case I'm seeing same received parameters on my grpc server.

Is there any way to be able to send empty strings?

"module google.golang.org/grpc@latest found (v1.32.0), but does not contain package google.golang.org/grpc/xds/experimental"

As the title says, upon trying to go get github.com/fullstorydev/grpcui/...

I am greeted with the following output

go: downloading github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
go: finding module for package google.golang.org/grpc/xds/experimental
go: finding module for package google.golang.org/grpc/xds/experimental
C:\Users\[username]\go\pkg\mod\github.com\fullstorydev\[email protected]\grpcurl.go:35:2: module google.golang.org/grpc@latest found (v1.32.0), but does not contain package google.golang.org/grpc/xds/experimental

I've no clue really what this error means, can anyone point me in the right direction?

[feature request] connect to multiple grpc services

This is a really good grpc frontend! I was planning to use it as a debugging/curl style hub for all our grpc backends. The problem I saw is that to support multiple backends, one has to run the command for each grpc service, and then expose it to different ports if the grpcui instances are deployed in one container.

Is it possible to connect to multiple grpc services with single exposed port and united UI? Is it possible for the UI to consolidate and support the selection for which service we want to talk to?

Thanks!

Error: Cant find package

Due to recent changes to introduce the github.com/pkg/browser and golang.org/x/crypto/ssh/terminal
I get error while build it from dockerfile Step 8/14 : RUN go install github.com/fullstorydev/grpcui/cmd/grpcui ---> Running in dbe088db5baa src/github.com/fullstorydev/grpcui/cmd/grpcui/grpcui.go:25:2: cannot find package "github.com/pkg/browser" in any of: /usr/local/go/src/github.com/pkg/browser (from $GOROOT) /go/src/github.com/pkg/browser (from $GOPATH) src/github.com/fullstorydev/grpcui/cmd/grpcui/grpcui.go:26:2: cannot find package "golang.org/x/crypto/ssh/terminal" in any of: /usr/local/go/src/golang.org/x/crypto/ssh/terminal (from $GOROOT) /go/src/golang.org/x/crypto/ssh/terminal (from $GOPATH)

Can you please help figuring out why is this happening.

use URL hash fragment to pin UI to a particular state

Currently, refreshing the grpcui page -- for example, to re-query for the remote service definition if the server is restarted with changes to its protocol -- resets everything. It changes tab to the request form, which gets blanked out. The service and method name drop-downs revert to whatever item is first in the list, instead of remembering what was previously selected.

It would be much nicer if the UI recorded its state in a hash fragment in the URL and could then reconstitute the UI state from that fragment when the page is loaded. That way, refreshing does not lose any of the data already entered.

Option to set the host and port from the web UI

At the moment, the host and port need to be specified on the command line, which makes it impossible to deploy an instance of gRPC UI somewhere and just use it when needed (at least if you work with multiple projects/environments).

wow. thanks.

many thanks for this work. terrifically useful to me.

Ability to view RPC history

If the details of each RPC invocation were include in the program output/logs, it could provide great utility for someone that wants to go back to previous RPCs they've sent in the same grpcui session. This would be particularly slick if they were in the form of grpcurl invocations (see #3) and could be easily pasted into any other grpcui session.

It might also be nice to have this sort of history in the browser -- maybe saved to local storage so that refreshing the page doesn't forget it all. (Use of local storage would likely need to be opt-in, so other places where the form is embedded could disable that to make sure it can't interfere with the host page.)

master not tagged

Any reason master has changes that aren't reflected in the latest tag? Go mod is fetching v1.0.0, but underlying changes in the import chain (grpcui -> grpcurl -> grpc-go) have breaking changes.

github.com/fullstorydev/grpcui/standalone imports
        github.com/fullstorydev/grpcui imports
        github.com/fullstorydev/grpcurl imports
        google.golang.org/grpc/xds/experimental: module google.golang.org/grpc@latest (v1.33.0) found, but does not contain package google.golang.org/grpc/xds/experimental

It looks like v1.0.0 depends on v1.6.0 of grpcurl, which has this line (https://github.com/fullstorydev/grpcurl/blob/v1.6.0/grpcurl.go#L35). You fixed it starting in v1.6.1, but no tagged version of this library has the fix.

Support for Oauth

I am protecting my APIs with oauth2 token, is there any way to make the authentication process and storage the id_token to send as metadata to my APIs?

Request metadata is not loaded when load history

Hi, i am big fan of grpcui.

I am using a lot of request (that include sort of request-metadatas).
So I use history loading feature many times.

But request-metadata is not loading. And it is very inconvenient for me.

Reproduce step

  • Send request with request metadata
    image
  • Click history and load (we can key metadata list in this page)
    image
  • Request metdata disappear
    image

Reflection throws error when targeting Google.Protobuff 3.9

@jhump this is not an issue against your project but I figured it's worth mentioning here in case others have upgraded to Protobuff 3.9 and can't run GRPCUI.

In short, if a GRPC server gets upgraded to use Protobuf 3.9 (latest version, released 4 days ago) and you try to run GRPCUI against it, reflection fails with error:

Method not found: 'Google.Protobuf.FieldCodec<Google.Protobuf.ByteString> Google.Protobuf.FieldCodec.ForBytes(UInt32)'.

I believe this is a result of an issue introduced in 3.9 and that is documented by the Protobuf team here.

Command-line options to set max message size for channel

Hi everyone,
I'm trying to get ByteString from server with content length is larger than max (6221671 vs. 4194304). With client in C# i'm using ChannelOptions with key is grpc.max_receive_message_length to set max length and can receive large file from Server. So in grpcUI how can i do that?

Thank for your help.

Install program

I have problems when install grpcui

cannot find package "github.com/cncf/udpa/go/udpa/core/v1" in any of:
        c:\go\src\github.com\cncf\udpa\go\udpa\core\v1 (from $GOROOT)
        C:\Users\<user>\go\src\github.com\cncf\udpa\go\udpa\core\v1 (from $GOPATH)

I found in cncf repository one change and exists another version without /v1 directory on master. @v0.0.1 is ok. But I'm no programming in Go to correct that

grpcui: command not found

I followed Installation and installed grpcui

go get github.com/fullstorydev/grpcui/...
go install github.com/fullstorydev/grpcui/cmd/grpcui

I also setted grpcui in my $PATH. I even tried with downloading this repo and make install. But I keep getting error grpcui: command not found. Anyone could help ?

run grpcui and got "Symbol not found: grpc.health.v1.Health"

hello,
I run grpcui 1.0.0 release on Windows and it failed.
E:>grpcui.exe -plaintext 127.0.0.1:50051
Failed to compute set of methods to expose: Symbol not found: grpc.health.v1.Health

but there is a grpc.health.v1.Health service, grpcurl can list it out.
E:>grpcurl.exe -plaintext 127.0.0.1:50051 list
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection
my_grpc.my_grpc_service

the service is wroten c++, almost same as the grpc example greeter_server.cc,
does anyone known how to resolve this issue?
thank you!

Releases?

Heya! Thanks for sharing this project, I immediately fell in love ๐Ÿ˜

What do you think about having releases? It would simplify packaging this up with; I'd like to create a habitat package similar to the one we have for grpcurl (see also habitat-sh/core-plans#2186).

Need tests for JS code

This repo includes about 2k lines of JavaScript code (most of the actual logic for the web UI), but does not have any JS tests (or even a JS test harness). We'll likely want to use PhantomJS or similar, since the JS code needs to run in the context of a browser and interact with page DOM elements.

Deploy grpcui with the grpc service

The grpc ui works great and I am able to access my service, but I am looking for a an alternate solution of if there is a way to deploy the toll with my grpc service itself, so that anyone can readily access it rather than every person install the tool locally.

What changes will I need to do to achieve that. Any anyone tried anything similar?

The grpcui interface opens without anything

image

This is my proto file

syntax = "proto3";

package proto.TestService.v1;

import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/api/annotations.proto";

option go_package = "api";
option (gogoproto.goproto_getters_all) = false;

service SearchService {
    rpc Search(SearchRequest) returns (SearchResponse) {
        option (google.api.http) = {
            get:"/abc/say_hello"
        };
    }
}

message SearchRequest {
    string request = 1 [(gogoproto.moretags)='form:"request" validate:"required"'];
}

message SearchResponse {
    string response = 1 [(gogoproto.jsontag) = 'response'];
}

My run command

 grpcui -import-path=E:/GOPATH/src/github.com/bilibili/kratos/third_party -proto=E:/GOPATH/src/github.com/bilibili/kratos/third_party/github.com/gogo/protobuf/gogoproto/gogo.proto -plaintext 127.0.0.1:9001

Service startup code

package main

import (
	"context"
	pb "kratos-demo/api"
	"log"
	"net"

	"google.golang.org/grpc/reflection"

	"google.golang.org/grpc"
)

type SearchService struct{}

func (s *SearchService) Search(ctx context.Context, r *pb.SearchRequest) (*pb.SearchResponse, error) {
	return &pb.SearchResponse{Response: "1111  Server"}, nil
}

const PORT = "9001"

func main() {
	server := grpc.NewServer()
	pb.RegisterSearchServiceServer(server, &SearchService{})
	lis, err := net.Listen("tcp", ":"+PORT)
	if err != nil {
		log.Fatalf("net.Listen err: %v", err)
	}
	reflection.Register(server)
	server.Serve(lis)
}

Looking forward to the answer to the question

Copy as "grpcurl"

A slick feature would be to be able to Copy as 'grpcurl' -- which would extract all connection info from command-line flags as well as the request metadata and data in the web form and use that to generate an equivalent grpcurl command.

Similarly, the ability to paste a grpcurl command, and have that auto-populate the metadata and request message data would be slick as well.

CSRF protection

The main package needs some way for embedded forms to enable CSRF protection. The standalone package (and thus the grpcui command-line tool, too) then need to use that mechanism to enable CSRF protection.

Initial idea on how to solve:

  1. Provide a func(r *http.Request) string function to grpcui.RPCInvokeHandler. If supplied, the handler will look for a custom header (X-CSRF-Token?) and make sure it matches the string returned by the given function.
  2. Update grpcui.WebFormScript to expose API (e.g. add exported functions to window) that can be used to set a CSRF token. If set, all calls to invocation handler will add it in custom header.
  3. In the standalone package, use a JS-visible cookie to track the CSRF token. When the main page is fetched, set the cookie if it's not present, generating new tokens using a secure RNG. The custom function given to grpcui.RPCInvokeHandler will retrieve the cookie value (and fail with a 401 Unauthorized if it does not exist). In the main page, in which the gRPC form is embedded, add a <script> tag that queries the cookie value and then calls the script's exported function to set its CSRF token.

Symbol not found: grpc.reflection.v1alpha.ServerReflection

On a server with reflection enabled (works fine with both grpcurl and grpcox), I get this error when running grpcui:

$ grpcui -vvv -bind 0.0.0.0 -port 8082 -plaintext localhost:4567
INFO: 2019/06/14 10:49:37 parsed scheme: ""
INFO: 2019/06/14 10:49:37 scheme "" not registered, fallback to default scheme
INFO: 2019/06/14 10:49:37 ccResolverWrapper: sending update to cc: {[{localhost:4567 0  <nil>}] }
INFO: 2019/06/14 10:49:37 ClientConn switching balancer to "pick_first"
INFO: 2019/06/14 10:49:37 pickfirstBalancer: HandleSubConnStateChange: 0xc00006ee30, CONNECTING
INFO: 2019/06/14 10:49:37 pickfirstBalancer: HandleSubConnStateChange: 0xc00006ee30, READY
Failed to compute set of methods to expose: Symbol not found: grpc.reflection.v1alpha.ServerReflection

Yocto integration

Hello,

I have a gRPC server running on an embedded target, built using Yocto. I wanted to use a debug website on the target so I can easily debug certain behavior which is linked to the gRPC Service. I've been able to run everything native perfectly, but when I wanted to integrate this project in Yocto I've had a bunch of issues: like not being able to find grpc-go (which is supported by openembedded).

Anyone any experience with this? Or can someone give some things I could look into?

Thanks a lot for the help!

Goran Broeckaert

Input fixed request metadata when execute grpcui

Hi!
In our project,
All requests require token in request-metadata for security

There is node A (grpc server), node B (grpcui)
node A and node B knows the token (by environment variable).
But user that connected to node B don't know the token.

User can't use grpcui (b/c node A require token for all requests, and they don't know the token)

So I want when execute grpcui, can input fixed request metdata.

For example, make new parameter -metadata key:value

grpcui -metadata token:password -metadata other_token:other_password localhost:8888

Thanks for reading.

Nodejs supporting

gRPC server is written by NodeJS. I have an issue with connecting.

Failed to compute set of methods to expose: server does not support the reflection API

retry upstream connection

I'm using grpcui in a docker-compose app. I've got a bit of a race condition where the upstream gRPC server often doesn't start before grpcui attempts to connect to it. I'm using docker-compose depends_on, but this doesn't work because the container with the gRPC service reports ready when the server process has started, and not when the server is actually ready to receive connections. There's normally a few seconds in it.

Grpcui is making one attempt to connect to the upstream service, and then exiting with an error code. What i'd really like is a way to specify that it should retry the upstream connection. Is there a clean way to do this?

Can't use negative values on int64

I can see in my local machine the commit (#29) that should fix this but I can't get it to work. I've tried deleting and installing again, but nothing works. Am I missing something?

facundo:grpcui facundomedica$ git log
commit 20f41010374fb569638f2d094776e27ffd1a0634 (HEAD -> master, origin/master, origin/HEAD)
Author: Joshua Humphries <[email protected]>
Date:   Tue Mar 26 14:46:20 2019 -0400

    fix range validation for 64-bit signed ints (#29)

must restart grpcui when connection to server is lost

If I start both grpcui and a gRPC server and then have to restart the gRPC server, the grpcui program gets into a bad state and must also be restarted.

The problem is due to the use of the original dial context in the custom dialer (in grpcurl's BlockingDial function), even for subsequent connect operations. So when the gRPC client in grpcui tries to re-establish a connection, it is using an expired context and so can never successfully reconnect.

This is fixed in the latest version of grpcurl. So we need a new release of grpcurl so that grpcui can depend on it in its go.mod file.

Unable to install

$ go get github.com/fullstorydev/grpcui
...
$ go install github.com/fullstorydev/grpcui/cmd/grpcui
# github.com/fullstorydev/grpcurl
../go/src/github.com/fullstorydev/grpcurl/grpcurl.go:600:4: undefined: grpc.WithContextDialer

standalone sub-path

handling at a sub-path via http.StripPrefix returns a 301 permanent redirect instead

It works with no sub-path and no StripPrefix.

to reproduce with go version go1.12.3 windows/amd64:

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"time"

	"golang.org/x/net/context"

	"github.com/fullstorydev/grpcui/standalone"
	"github.com/fullstorydev/grpcurl"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

var (
	port   string
	target string
)

func init() {
	port = os.Getenv("PORT")
	if port == "" {
		port = "8000"
	}
	target = os.Getenv("TARGET")
}

func main() {
	ctx := context.Background()
	dialTime := 10 * time.Second
	ctx, cancel := context.WithTimeout(ctx, dialTime)
	defer cancel()
	var opts []grpc.DialOption
	var creds credentials.TransportCredentials
	network := "tcp"
	cc, err := grpcurl.BlockingDial(ctx, network, target, creds, opts...)
	if err != nil {
		log.Fatalf("Failed to dial target host %q", target)
	}
	h, err := standalone.HandlerViaReflection(ctx, cc, target)
	if err != nil {
		log.Fatalf("Reflection failed on target host %q", target)
	}
	http.Handle("/grpcui/", http.StripPrefix("/grpcui/", h))
	log.Fatal(http.ListenAndServe(":"+port, nil))
}
$ curl -v localhost:8000/grpcui/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /grpcui/ HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.63.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=utf-8
< Location: /
< Set-Cookie: _grpcui_csrf_token=<------------------------------------->
< Date: Thu, 27 Jun 2019 22:55:17 GMT
< Content-Length: 36
<
<a href="/">Moved Permanently</a>.

* Connection #0 to host localhost left intact

Incompatible with validators

Tested with both github.com/mwitkow/go-proto-validators and github.com/envoyproxy/protoc-gen-validate/, it all failed with File not found errors.

This is caused by these validators lib not registering themselves into reflection. However, these protos are used in field/method options, and in fact not actual dependencies to make the GRPC call.

Our current workaround is to fork the underlying project jhump/protoreflect, and provide an opt-out option to ignore failure to reflect these lib.

Looking forward to a better solution.

Support file upload for bytes fields

Would you be open to an MR to show a file upload in addition to the current base64 encoded textbox for bytes fields?

The implementation requires following changes:

Change the switch case to a different render method addBytesToForm

case "bytes": case "google.protobuf.BytesValue":
return addStringToForm(container, parent, value, fld, true);

This addBytesToForm would show two inputs, a string and a file button. The string would behave as it does and the file button would handle onchange to populate a base64 encoded byte string (which is set on the message and the string input).

I can put together a quick MR for this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.