4.3 KiB
title, date, draft, tags, archive, series, featuredImage
title | date | draft | tags | archive | series | featuredImage | |||||
---|---|---|---|---|---|---|---|---|---|---|---|
Evans - a CLI gRPC Client | 2020-08-18 | false |
|
|
/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 here, many will also use Postman. But some people will simply use cURL. 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.
Installation & Setup
Installation is easiest on MacOS:
brew tap ktr0731/evans
brew install evans
Binaries for Linux and Windows are also available on Github.
In order to be able to use Evans effectively, I definitely recommend switching on gRPC Reflection. In Go this could look like this:
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
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.
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.
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:
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.
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:
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 is an electron client for gRPC with a nice GUI. Who e.g. is familiar with GraphiQL you will quickly find your way around here.
gRPC Curl is certainly an option for some.