This repository has been archived on 2024-11-25. You can view files and clone it, but cannot push or open issues or pull requests.
m3tam3re.com/content/posts/evans-grpc.en.md
2023-10-12 14:01:05 +02:00

158 lines
4.3 KiB
Markdown

---
title: "Evans - a CLI gRPC Client"
date: 2020-08-18
draft: false
tags: ["grpc","protobuf","cli"]
archive: ["Technical Stuff"]
series: [""]
featuredImage: "/img/evans/evans.gif"
---
# gRPC Server testing, but how?
If you develop a REST or GraphQL Api you have various tools available that support you in testing. I personally use [Insomnia](https://insomnia.rest) here, many will also use [Postman](https://www.postman.com/).
But some people will simply use [cURL](https://curl.haxx.se/). Such tools appear to be less common for gRPC.
A tool that I find very useful and that helps me when I work with a gRPC service is [Evans](https://github.com/ktr0731/evans).
## Installation & Setup
Installation is easiest on MacOS:
```bash
brew tap ktr0731/evans
brew install evans
```
Binaries for Linux and Windows are also available on [Github](https://github.com/ktr0731/evans).
In order to be able to use Evans effectively, I definitely recommend switching on gRPC Reflection. In Go this could look like this:
```go
package main
import (
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"log"
"net"
pb "path/to/your/compiled/protobuf/package"
)
var port = ":50051"
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterExampleserviceServer(s, &exampleService)
// Enable reflection:
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
```
## First Steps
Evans starts in repl mode with
```bash
evans -r -p 50051
```
If Reflection enabled as described above, you can display the available services with show package and switch to a service with packache ServiceName.
![Start Evans](/img/evans/evans1.gif "Start Evans")
## Reflection
The whole point, of course, is to test RPCs. Here, too, reflection helps us. If you have chosen a package you can use show Service to display which services are available in the package.
![Service Info](/img/evans/evans2.gif "Select a service")
The nice thing is that you can also see the RPCs including request and response types.
To be able to work with the service, it must be selected. service ServiceName selects a service and now you can display the available RPCs with show rpc:
![RPCs](/img/evans/evans3.gif "Show RPCs")
## Call RPCs
With call RPCname you can now call RPCs. In my example here, I am calling Save. Evans now asks interactively the individual fields that are necessary for the call.
![Call RPCs](/img/evans/evans5.gif "Call RPCs")
As you can see, further information is also displayed here. repeate indicates that addresslist is an array and what type the individual fields are. The protobuf file looks like this:
```protobuf
syntax = "proto3";
package address;
import "helper/helper.proto";
option go_package = "models/address";
service AddressService {
rpc GetSingleAddress (address.GetAddressRequest) returns (address.Address) {}
rpc GetAddressList (address.GetAddressRequest) returns (address.AddressList) {}
rpc Save (address.AddressList) returns (helper.StatusResponse) {}
rpc Delete (address.AddressList) returns (helper.StatusResponse) {}
}
message GetAddressRequest {
string id = 1;
}
message Address {
string id = 1;
string firstName = 2;
string lastName = 3;
string company = 4;
string address1 = 5;
string address2 = 6;
string zip = 7;
string city = 8;
Country country = 9;
}
message AddressList {
repeated address.Address addresslist = 1;
}
enum Country {
option allow_alias = true;
AL = 0 ;
AD = 1 ;
AT = 2 ;
BY = 3 ;
BE = 4 ;
...
ALBANIA = 0 ;
ANDORRA = 1 ;
AUSTRIA = 2 ;
BELARUS = 3 ;
BELGIUM = 4 ;
...
}
```
## Conclusion and alternatives
Of course, this can only serve as an overview. Evans can do a lot more, including streaming testing.
Personally, I think it makes testing a lot easier. I think it's a good thing that it's a CLI tool, because you don't always have a GUI available.
There are of course alternatives. e.g. [Bloom RPC](https://github.com/uw-labs/bloomrpc) is an electron client for gRPC with a nice GUI. Who e.g. is familiar with [GraphiQL](https://github.com/graphql/graphiql) you will quickly find your way around here.
[gRPC Curl](https://github.com/fullstorydev/grpcurl) is certainly an option for some.