--- title: "Evans - ein CLI gRPC Client" date: 2020-08-18 draft: false tags: ["grpc","protobuf","cli"] archive: ["Technik Zeug"] series: [""] featuredImage: "/img/evans/evans.gif" --- # gRPC Server testen, aber wie? Wenn man eine REST oder GraphQL Api entwickelt hat man diverse Tools zur Verfügung, die einen beim Testen unterstützen. Ich persönlich setze hier [Insomnia](https://insomnia.rest) ein, viele werden auch [Postman](https://www.postman.com/) verwenden. Manch einer wird aber auch einfach [cURL](https://curl.haxx.se/) verwenden. Für gRPC scheinen solche Tools weniger weit verbreitet zu sein. Ein Tool, dass ich sehr nützlich finde und dass mir hilft, wenn ich mit einem gRPC Service arbeite ist [Evans](https://github.com/ktr0731/evans). ## Installation & Setup Die Installation ist unter MacOS am einfachsten: ```bash brew tap ktr0731/evans brew install evans ``` Binaries für Linux und Windows sind auf [Github](https://github.com/ktr0731/evans) ebenfalls verfügbar. Um Evans effektiv nutzen zu könnnen, empfehle ich auf jeden Fall gRPC Reflection einzuschalten. In Go könnte das so aussehen: ```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) } } ``` ## Erste Schritte Evans startet Ihr z.B. im Repl Modus mit: ```bash evans -r -p 50051 ``` Ist Reflection so wie oben beschrieben eingeschaltet könnt Ihr Euch mit show package die verfügbaren Services anzeigen lassen und mit packache ServiceName zu einem Service wechseln. ![Evans starten](/img/evans/evans1.gif "Evans starten") ## Reflektion Sinn und zweck des Ganzen ist aber natürlich das Testen RPCs. Auch hier hilft uns die Reflektion. Wenn Ihr ein package gewählt habt könnt Ihr Euch mit show Service anzeigen lassen welche Services in dem Paket verfügbar sind. ![Service Info](/img/evans/evans2.gif "Einen Service auswählen") Das Schöne ist, dass Euch die RPCs samt Request- und Responsetypen ebenfalls angezeigt werden. Um mit dem Service arbeiten zu können muss dieser ausgewählt werden. service ServiceName wählt einen Service aus und nun könnnt Ihr Euch mit show rpc die verfügbaren RPCs anzeigen lassen: ![RPCs](/img/evans/evans3.gif "RPCs anzeigen lassen") ## RPCs aufrufen Mit call RPCname könnt Ihr jetzt RPCs aufrufen. In meinem Beispiel hier rufe ich Save auf. Evans fragt nun interaktiv die einzelnen Felder ab, diee für den Aufruf notwendig sind. ![RPCs aufrufen](/img/evans/evans5.gif "RPCs aufrufen") Wie man sieht bekommt man hier auch noch weitere Infos angezeigt. Repeate zeigt uns, dass addresslist ein Array ist un welchem Typ die einzelnen Felder sind. Die protobuf Datei dazu sieht so aus: ```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 ; ... } ``` ## Fazit und Alternativen Das kann natürlich erst einmal nur als Überblick dienen. Evans kann noch einiges mehr, unter anderem kann damit auch Streaming getestet werden. Ich persönlich finde, dass das Testen dadurch um einiges leichter wird. Dass es sich um ein CLI tool handelt, finde ich gerade gut, da man ja nicht immer unbedingt ein GUI zur Verfügung hat. Alternativen gibt es natürlich auch. z.B. [Bloom RPC](https://github.com/uw-labs/bloomrpc) ist ein Electron Client für gRPC mit einem schicken GUI. Wer z.B. mit [GraphiQL](https://github.com/graphql/graphiql) vertraut ist wird sich hier schnell zurechtfinden. [gRPC Curl](https://github.com/fullstorydev/grpcurl) ist für einige mit Sicherheit auch eine Möglichkeit.