grpcurl
is a command-line tool that lets you interact with gRPC servers. It's basically curl
for gRPC servers.
The main purpose for this tool is to invoke RPC methods on a gRPC server from the command-line. gRPC servers use a binary encoding on the wire (protocol buffers, or "protobufs" for short). So they are basically impossible to interact with using regular curl
(and older versions of curl
that do not support HTTP/2 are of course non-starters). This program accepts messages using JSON encoding, which is much more friendly for both humans and scripts.
With this tool you can also browse the schema for gRPC services, 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 grpcurl
can use.
This repo also provides a library package, github.com/fullstorydev/grpcurl
, that has functions for simplifying the construction of other command-line tools that dynamically invoke gRPC endpoints. This code is a great example of how to use the various packages of the protoreflect library, and shows off what they can do.
See also the grpcurl
talk at GopherCon 2018.
grpcurl
supports all kinds of RPC methods, including streaming methods. You can even operate bi-directional streaming methods interactively by running grpcurl
from an interactive terminal and using stdin as the request body!
grpcurl
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, grpcurl
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 grpcurl
.
Download the binary from the releases page.
On macOS, grpcurl
is available via Homebrew:
brew install grpcurl
You can use the go
tool to install grpcurl
:
go get github.com/fullstorydev/grpcurl go install github.com/fullstorydev/grpcurl/cmd/grpcurl
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 grpcurl
's dependencies. You can update the dependencies by running make updatedeps
. You can also use vgo
to install, which will use the right versions of dependencies. Or, if you are using Go 1.11, you can add GO111MODULE=on
as a prefix to the commands above, which will also build using the right versions of dependencies (vs. whatever you may already in your GOPATH
).
The usage doc for the tool explains the numerous options:
grpcurl -help
In the sections below, you will find numerous examples demonstrating how to use grpcurl
.
Invoking an RPC on a trusted server (e.g. TLS without self-signed key or custom CA) that requires no client certs and supports server reflection is the simplest thing to do with grpcurl
. This minimal invocation sends an empty request body:
grpcurl grpc.server.com:443 my.custom.server.Service/Method
To send a non-empty request, use the -d
argument. Note that all arguments must come before the server address and method name:
grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \ grpc.server.com:443 my.custom.server.Service/Method
As can be seen in the example, the supplied body must be in JSON format. The body will be parsed and then transmitted to the server in the protobuf binary format.
If you want to include grpcurl
in a command pipeline, such as when using jq
to create a request body, you can use -d @
, which tells grpcurl
to read the actual request body from stdin:
grpcurl -d @ grpc.server.com:443 my.custom.server.Service/Method <<EOM { "id": 1234, "tags": [ "foor", "bar" ] } EOM
To list all services exposed by a server, use the "list" verb. When using .proto
source or protoset files instead of server reflection, this lists all services defined in the source or protoset files.
# Server supports reflection grpcurl localhost:8787 list # Using compiled protoset files grpcurl -protoset my-protos.bin list # Using proto sources grpcurl -import-path ../protos -proto my-stuff.proto list
The "list" verb also lets you see all methods in a particular service:
grpcurl localhost:8787 list my.custom.server.Service
The "describe" verb will print the type of any symbol that the server knows about or that is found in a given protoset file. It also prints a description of that symbol, in the form of snippets of proto source. It won't necessarily be the original source that defined the element, but it will be equivalent.
# Server supports reflection grpcurl localhost:8787 describe my.custom.server.Service.MethodOne # Using compiled protoset files grpcurl -protoset my-protos.bin describe my.custom.server.Service.MethodOne # Using proto sources grpcurl -import-path ../protos -proto my-stuff.proto describe my.custom.server.Service.MethodOne
The grpcurl
tool can operate on a variety of sources for descriptors. The descriptors are required, in order for grpcurl
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.
Without any additional command-line flags, grpcurl
will try to use server reflection.
Examples for how to set up server reflection can be found here.
When using reflection, the server address (host:port or path to Unix socket) is required even for "list" and "describe" operations, so that grpcurl
can connect to the server and ask it for its descriptors.
To use grpcurl
on servers that do not support reflection, you can use .proto
source files.
In addition to using -proto
flags to point grpcurl
at the relevant proto source file(s), you may also need to supply -import-path
flags to tell grpcurl
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 grpcurl
as a snapshot of their descriptors is built into the grpcurl
binary.
When using proto sources, you can omit the server address (host:port or path to Unix socket) when using the "list" and "describe" operations since they only need to consult the proto source files.
You can also use compiled protoset files with grpcurl
. If you are scripting grpcurl
and need to re-use the same proto sources for many invocations, you will see better performance by using protoset files (since it skips the parsing and compilation steps with each invocation).
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 grpcurl
needs to process and understand the schema.
When using protosets, you can omit the server address (host:port or path to Unix socket) when using the "list" and "describe" operations since they only need to consult the protoset files.