All Projects → ktr0731 → Evans

ktr0731 / Evans

Licence: mit
Evans: more expressive universal gRPC client

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to Evans

Protodot
transforming your .proto files into .dot files (and .svg, .png if you happen to have graphviz installed)
Stars: ✭ 107 (-96.05%)
Mutual labels:  grpc, cli, protocol-buffers
Mu Haskell
Mu (μ) is a purely functional framework for building micro services.
Stars: ✭ 215 (-92.07%)
Mutual labels:  grpc, protocol-buffers, rpc
Go Micro Boilerplate
The boilerplate of the GoLang application with a clear microservices architecture.
Stars: ✭ 147 (-94.58%)
Mutual labels:  grpc, protocol-buffers, rpc
Protodep
Collect necessary .proto files (Protocol Buffers IDL) and manage dependencies
Stars: ✭ 167 (-93.84%)
Mutual labels:  grpc, cli, protocol-buffers
Go Grpc Examples
This repo contains examples and implementations of different types of GRPC services and APIs using Golang.
Stars: ✭ 180 (-93.36%)
Mutual labels:  grpc, protocol-buffers, rpc
Armeria
Your go-to microservice framework for any situation, from the creator of Netty et al. You can build any type of microservice leveraging your favorite technologies, including gRPC, Thrift, Kotlin, Retrofit, Reactive Streams, Spring Boot and Dropwizard.
Stars: ✭ 3,392 (+25.17%)
Mutual labels:  grpc, rpc, grpc-client
Protobuf
Protocol Buffers - Google's data interchange format
Stars: ✭ 52,305 (+1830.07%)
Mutual labels:  protocol-buffers, rpc
Twirp
PHP port of Twitch's Twirp RPC framework
Stars: ✭ 108 (-96.01%)
Mutual labels:  protocol-buffers, rpc
Purerpc
Asynchronous pure Python gRPC client and server implementation supporting asyncio, uvloop, curio and trio
Stars: ✭ 125 (-95.39%)
Mutual labels:  grpc, rpc
Protoeasy Go
Simpler usage of protoc. Deprecated.
Stars: ✭ 129 (-95.24%)
Mutual labels:  grpc, protocol-buffers
Pool
General Purpose Connection Pool for GRPC,RPC,TCP Sevice Cluster
Stars: ✭ 98 (-96.38%)
Mutual labels:  grpc, rpc
Go Proto Gql
Protobuff plugins for generating graphql schema and golang to graphql bindings. Also supports a graphql gateway (Alpha)
Stars: ✭ 127 (-95.31%)
Mutual labels:  grpc, protocol-buffers
Noproto
Flexible, Fast & Compact Serialization with RPC
Stars: ✭ 138 (-94.91%)
Mutual labels:  protocol-buffers, rpc
Protoc Gen Struct Transformer
Transformation functions generator for Protocol Buffers.
Stars: ✭ 105 (-96.13%)
Mutual labels:  grpc, protocol-buffers
Rpc Framework Tutorials
Java分布式RPC服务框架教程,包括 Dubbo/Dubbox, Motan, gRPC.
Stars: ✭ 114 (-95.79%)
Mutual labels:  grpc, rpc
Shtab
↔️ Automagic shell tab completion for Python CLI applications
Stars: ✭ 99 (-96.35%)
Mutual labels:  cli, completion
Go Grpc
A collection of gRPC and Go examples showcasing features of the framework
Stars: ✭ 127 (-95.31%)
Mutual labels:  grpc, rpc
Protolint
A pluggable linter and fixer to enforce Protocol Buffer style and conventions.
Stars: ✭ 142 (-94.76%)
Mutual labels:  cli, protocol-buffers
Discordrpcmaker
Cross-platform Discord Rich Presence Maker, WITH BUTTONS!
Stars: ✭ 165 (-93.91%)
Mutual labels:  cli, rpc
Grpc Swift
The Swift language implementation of gRPC.
Stars: ✭ 1,270 (-53.14%)
Mutual labels:  grpc, protocol-buffers

Evans


GitHub Actions codecov PkgGoDev

Motivation

Evans has been created to use easier than other existing gRPC clients.
If you want to keep your product quality, you must use CI with gRPC testing, should not do use manual testing.
Evans will complete your other use cases just like:

  • Manually gRPC API inspection
  • To automate some tasks by scripting

The above use cases are corresponding to Evans's two modes, REPL mode, and CLI mode.

REPL mode

Evans
REPL mode is the solution for first use case.
You can use it without thinking like the package name, service name, RPC name, command usage, and so on because REPL mode has powerful completion!

CLI mode

Evans

CLI mode is a stateless mode just like grpc-ecosystem/polyglot.
It sends one request per one command as its name suggests.
So it is based on UNIX philosophy.

For example, read inputs from stdin, the command will be a filter command.
On the other hand, the command result will be outputted to stdout by JSON formatted.
So, you can format it by any commands like jq. Also, if you want to use the same command (e.g. use same JSON inputs), you can use --file (-f) option.

Table of Contents

Installation

Highly recommended methods are GitHub Releases or Homebrew because these can be updated automatically by the built-in feature in Evans.

From GitHub Releases

Please see GitHub Releases.
Available binaries are:

  • macOS
  • Linux
  • Windows

macOS

$ brew tap ktr0731/evans
$ brew install evans

[Not-recommended] go install

Go v1.16 or later is required.

$ go install github.com/ktr0731/evans@latest

Usage (REPL)

Basic usage

Evans consists of some commands in REPL mode.

The proto file which read in the demonstration and its implementation are available at ktr0731/grpc-test.
grpc-test's details can see grpc-test --help.

Enter to REPL.

$ cd grpc-test
$ evans repl api/api.proto

If your server is enabling gRPC reflection, you can launch Evans with only -r (--reflection) option.

$ evans -r repl

Also if the server requires secure TLS connections, you can launch Evans with the -t (--tls) option.

$ evans --tls --host example.com -r repl

To show package names of proto files REPL read:

> show package
+---------+
| PACKAGE |
+---------+
| api     |
+---------+

To show the summary of services or messages:

> package api
> show service
+---------+----------------------+-----------------------------+----------------+
| SERVICE |         RPC          |         REQUESTTYPE         |  RESPONSETYPE  |
+---------+----------------------+-----------------------------+----------------+
| Example | Unary                | SimpleRequest               | SimpleResponse |
|         | UnaryMessage         | UnaryMessageRequest         | SimpleResponse |
|         | UnaryRepeated        | UnaryRepeatedRequest        | SimpleResponse |
|         | UnaryRepeatedMessage | UnaryRepeatedMessageRequest | SimpleResponse |
|         | UnaryRepeatedEnum    | UnaryRepeatedEnumRequest    | SimpleResponse |
|         | UnarySelf            | UnarySelfRequest            | SimpleResponse |
|         | UnaryMap             | UnaryMapRequest             | SimpleResponse |
|         | UnaryMapMessage      | UnaryMapMessageRequest      | SimpleResponse |
|         | UnaryOneof           | UnaryOneofRequest           | SimpleResponse |
|         | UnaryEnum            | UnaryEnumRequest            | SimpleResponse |
|         | UnaryBytes           | UnaryBytesRequest           | SimpleResponse |
|         | ClientStreaming      | SimpleRequest               | SimpleResponse |
|         | ServerStreaming      | SimpleRequest               | SimpleResponse |
|         | BidiStreaming        | SimpleRequest               | SimpleResponse |
+---------+----------------------+-----------------------------+----------------+

> show message
+-----------------------------+
|           MESSAGE           |
+-----------------------------+
| SimpleRequest               |
| SimpleResponse              |
| Name                        |
| UnaryMessageRequest         |
| UnaryRepeatedRequest        |
| UnaryRepeatedMessageRequest |
| UnaryRepeatedEnumRequest    |
| UnarySelfRequest            |
| Person                      |
| UnaryMapRequest             |
| UnaryMapMessageRequest      |
| UnaryOneofRequest           |
| UnaryEnumRequest            |
| UnaryBytesRequest           |
+-----------------------------+

To show more description of a message:

> desc SimpleRequest
+-------+-------------+
| FIELD |    TYPE     |
+-------+-------------+
| name  | TYPE_STRING |
+-------+-------------+

Set headers for each request:

> header foo=bar

To show headers:

> show header
+-------------+-------+
|     KEY     |  VAL  |
+-------------+-------+
| foo         | bar   |
| grpc-client | evans |
+-------------+-------+

Note that if you want to set comma-included string to a header value, it is required to specify --raw option.

To remove the added header:

> header foo
> show header
+-------------+-------+
|     KEY     |  VAL  |
+-------------+-------+
| grpc-client | evans |
+-------------+-------+

Call a RPC:

> service Example
> call Unary
name (TYPE_STRING) => ktr
{
  "message": "hello, ktr"
}

Evans constructs a gRPC request interactively and sends the request to a gRPC server.
Finally, Evans prints the JSON formatted result.

Repeated fields

repeated is an array-like data structure.
You can input some values and finish with CTRL-D

> call UnaryRepeated
<repeated> name (TYPE_STRING) => foo
<repeated> name (TYPE_STRING) => bar
<repeated> name (TYPE_STRING) => baz
<repeated> name (TYPE_STRING) =>
{
  "message": "hello, foo, bar, baz"
}

Enum fields

You can select one from the proposed selections.
When CTRL-C is entered, default value 0 will be used.
When CTRL-D is entered, inputting will be aborted.

> call UnaryEnum
? UnaryEnumRequest  [Use arrows to move, type to filter]
> Male
  Female
{
  "message": "M"
}

Bytes type fields

You can use byte literal and Unicode literal.

> call UnaryBytes
data (TYPE_BYTES) => \x46\x6f\x6f
{
  "message": "received: (bytes) 46 6f 6f, (string) Foo"
}

> call UnaryBytes
data (TYPE_BYTES) => \u65e5\u672c\u8a9e
{
  "message": "received: (bytes) e6 97 a5 e6 9c ac e8 aa 9e, (string) 日本語"
}

Or add the flag --bytes-from-file to read bytes from the provided relative path

> call UnaryBytes --bytes-from-file
data (TYPE_BYTES) => ../relative/path/to/file

Client streaming RPC

Client streaming RPC accepts some requests and then returns only one response.
Finish request inputting with CTRL-D

> call ClientStreaming
name (TYPE_STRING) => ktr
name (TYPE_STRING) => ktr
name (TYPE_STRING) => ktr
name (TYPE_STRING) =>
{
  "message": "ktr, you greet 3 times."
}

Server streaming RPC

Server streaming RPC accepts only one request and then returns some responses. Each response is represented as another JSON formatted output.

name (TYPE_STRING) => ktr
{
  "message": "hello ktr, I greet 0 times."
}

{
  "message": "hello ktr, I greet 1 times."
}

Bidirectional streaming RPC

Bidirectional streaming RPC accepts some requests and returns some responses corresponding to each request. Finish request inputting with CTRL-D

> call BidiStreaming
name (TYPE_STRING) => foo
{
  "message": "hello foo, I greet 0 times."
}

{
  "message": "hello foo, I greet 1 times."
}

{
  "message": "hello foo, I greet 2 times."
}

name (TYPE_STRING) => bar
{
  "message": "hello bar, I greet 0 times."
}

name (TYPE_STRING) =>

Skip the rest of the fields

Evans recognizes CTRL-C as a special key that skips the rest of the fields in the current message type. For example, we assume that we are inputting Request described in the following message:

message FullName {
  string first_name = 1;
  string last_name = 2;
}

message Request {
  string nickname = 1;
  FullName full_name = 2;
}

If we enter CTRL-C at the following moment, full_name field will be skipped.

nickname (TYPE_STRING) =>

The actual request value is just like this.

{}

If we enter CTRL-C at the following moment, last_name field will be skipped.

nickname (TYPE_STRING) => myamori
full_name::first_name (TYPE_STRING) => aoi
full_name::last_name (TYPE_STRING) =>

The actual request value is just like this.

{
  "nickname": "myamori",
  "fullName": {
    "firstName": "aoi"
  }
}

By default, Evans digs down each message field automatically.
For example, we assume that we are inputting Request described in the following message:

message FullName {
  string first_name = 1;
  string last_name = 2;
}

message Request {
  FullName full_name = 1;
}

In this case, REPL prompts full_name.first_name automatically. To skip full_name itself, we can use --dig-manually option. It asks whether dig down a message field when the prompt encountered it.

Enriched response

To display more enriched response, you can use --enrich option.

> call --enrich Unary
name (TYPE_STRING) => ktr
content-type: application/grpc
header_key1: header_val1
header_key2: header_val2

{
  "message": "hello, ktr"
}

trailer_key1: trailer_val1
trailer_key2: trailer_val2

code: OK
number: 0
message: ""

Repeat the previous call

With --repeat option, you can repeat the previous call with the same input.
Note that Client/Bidirectional streaming RPC is not supported.

> call Unary
name (TYPE_STRING) => ktr
{
  "message": "hello, ktr"
}

> call --repeat Unary
name (TYPE_STRING) => ktr
{
  "message": "hello, ktr"
}

Usage (CLI)

Basic usage

CLI mode also has some commands.

list command provides gRPC service inspection against to the gRPC server.

$ evans -r cli list
api.Example
grpc.reflection.v1alpha.ServerReflection

If an service name is specified, it displays methods belonging to the service.

$ evans -r cli list api.Example
api.Example.Unary
api.Example.UnaryBytes
api.Example.UnaryEnum
...

desc command describes the passed symbol (service, method, message, and so on).

api.Example:
service Example {
  rpc Unary ( .api.SimpleRequest ) returns ( .api.SimpleResponse );
  rpc UnaryBytes ( .api.UnaryBytesRequest ) returns ( .api.SimpleResponse );
  rpc UnaryEnum ( .api.UnaryEnumRequest ) returns ( .api.SimpleResponse );
  ...
}

call command invokes a method. You can input requests from stdin or files.

Use --file (-f) to specify a file.

$ cat request.json
{
  "name": "ktr"
}

$ evans --proto api/api.proto cli call --file request.json api.Example.Unary
{
  "message": "hello, ktr"
}

If gRPC reflection is enabled, --reflection (-r) is available instead of specifying proto files.

$ evans -r cli call --file request.json api.Example.Unary
{
  "message": "hello, ktr"
}

Use stdin.

$ echo '{ "name": "ktr" }' | evans cli call api.Example.Unary
{
  "message": "hello, ktr"
}

If .evans.toml is exist in Git project root, you can denote default values.

[default]
protoFile = ["api/api.proto"]
package = "api"
service = "Example"

Then, the command will be more clear.

$ echo '{ "name": "ktr" }' | evans cli call Unary
{
  "message": "hello, ktr"
}

Repeated fields

$ echo '{ "name": ["foo", "bar"] }' | evans -r cli call api.Example.UnaryRepeated
{
  "message": "hello, foo, bar"
}

Enum fields

$ echo '{ "choice": 0 }' | evans -r cli call api.Example.UnaryEnum
{
  "message": "1"
}

Bytes type fields

You need to encode bytes by Base64.
This constraint is come from Go's standard package encoding/json

$ echo 'Foo' | base64
Rm9vCg==

$ echo '{"data": "Rm9vCg=="}' | evans -r cli call api.Example.UnaryBytes

Client streaming RPC

$ echo '{ "name": "ktr" } { "name": "ktr" }' | evans -r cli call api.Example.ClientStreaming
{
  "message": "ktr, you greet 2 times."
}

Server streaming RPC

$ echo '{ "name": "ktr" }' | evans -r cli call api.Example.ServerStreaming
{
  "message": "hello ktr, I greet 0 times."
}

{
  "message": "hello ktr, I greet 1 times."
}

{
  "message": "hello ktr, I greet 2 times."
}

Bidirectional streaming RPC

$ echo '{ "name": "foo" } { "name": "bar" }' | evans -r cli call api.Example.BidiStreaming
{
  "message": "hello foo, I greet 0 times."
}

{
  "message": "hello foo, I greet 1 times."
}

{
  "message": "hello foo, I greet 2 times."
}

{
  "message": "hello foo, I greet 3 times."
}

{
  "message": "hello bar, I greet 0 times."
}

Enriched response

To display more enriched response, you can use --enrich option.

$ echo '{"name": "ktr"}' | evans -r cli call --enrich api.Example.Unary                                                                                     ~/.ghq/src/github.com/ktr0731/grpc-test master
content-type: application/grpc
header_key1: header_val1
header_key2: header_val2

{
  "message": "hello, ktr"
}

trailer_key1: trailer_val1
trailer_key2: trailer_val2

code: OK
number: 0
message: ""

JSON output is also available with --json option.

Other features

gRPC-Web

Evans also support gRPC-Web protocol.
Tested gRPC-Web implementations are:

At the moment TLS is not supported for gRPC-Web.

Supported IDL (interface definition language)

Supported Codec

Supported Compressor

See Also

Evans (DJ YOSHITAKA)
Evans

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].