{"id":521,"date":"2019-06-01T22:01:13","date_gmt":"2019-06-01T20:01:13","guid":{"rendered":"https:\/\/magdy.dev\/blog\/?p=521"},"modified":"2019-06-01T22:01:33","modified_gmt":"2019-06-01T20:01:33","slug":"grpc-in-action","status":"publish","type":"post","link":"https:\/\/magdy.dk\/blog\/2019\/06\/01\/grpc-in-action\/","title":{"rendered":"gRPC in Action"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In this article, we will learn about gRPC and how we can use it by examples.<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">First: What is&nbsp;gRPC?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">let\u2019s take part of the word first, RPC: stands for Remote Procedure Call and it\u2019s a mechanism used when you have client-server model in a shared network to transfer the data between the client and the server through a synchronous process and it\u2019s called \u201cUnary\u201d which means when you send request you wait to get the response from the server, it also supports streaming from the client to the server, the opposite or bidirectional.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RPC is usually used with distributed systems(microservices) to allow the services to communicate with each other in an easy, fast and efficient way.<br>It can be services with many different languages and technologies or with even the same language, and you don\u2019t have to write a lot of boilerplate code to configure it, it\u2019s dead easy to use.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, what is gRPC?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It\u2019s an opensource RPC project developed by Google, uses HTTP\/2 for transport and Protocol Buffer (Protobuf) for efficient and fast data serialization.<\/p>\n\n\n\n<ul class=\"wp-block-gallery columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\"><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"552\" height=\"327\" src=\"https:\/\/magdy.dev\/blog\/wp-content\/uploads\/2019\/06\/grpc_image.png\" alt=\"\" data-id=\"523\" data-link=\"https:\/\/magdy.dev\/blog\/?attachment_id=523\" class=\"wp-image-523\" srcset=\"https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_image.png 552w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_image-300x178.png 300w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_image-320x190.png 320w\" sizes=\"auto, (max-width: 552px) 100vw, 552px\" \/><figcaption>Source: grpc.io<\/figcaption><\/figure><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">gRPC supports many languages such as C#, Java, Python and more you check the supported languages from&nbsp;<a href=\"https:\/\/grpc.io\/docs\/reference\/\" rel=\"noreferrer noopener\" target=\"_blank\">this link<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will learn the basic concepts of gRPC by doing, we will write a simple service in go to deal with user accounts as a server and use C# as a client to call and use it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Defining the service and message types by using Protobuf.<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">let\u2019s create a file called&nbsp;<em>account.proto<\/em><br><\/p>\n\n\n\n<pre class=\"line-numbers\" dir=\"ltr\"><code class=\"language-protobuf\">syntax = \"proto3\";\n\npackage accountproto;\n\nmessage CreateAccountRequest{\n    string username = 1;\n    string email = 2;\n}\n\nmessage CreateAccountResponse{\n    string id = 1;\n}\n\nmessage GetAccountInformationRequest{\n    string id = 1;\n}\n\nmessage GetAccountInformationResponse{\n    string id = 1;\n    string username = 2;\n    string email = 3;\n}\n\nservice AccountService{\n    rpc CreateAccount(CreateAccountRequest) returns (CreateAccountResponse){}\n    rpc GetAccountInformation(GetAccountInformationRequest) returns (GetAccountInformationResponse){}\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">At the begging, we specified that we will use proto3 which is the latest version of protocol buffers language, if we didn\u2019t specify it, it will assume that we\u2019re using proto2 and we don\u2019t want this to happen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After that, we specified the package name which will be the package name in go or the namespace in C# later, for more information check&nbsp;<a href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/proto3#packages\" rel=\"noreferrer noopener\" target=\"_blank\">the link<\/a>.<br>The rest of the file consists of messages and service.<br>A&nbsp;<strong>message<\/strong>&nbsp;is what will be input or output from a service method which we define after, properties inside the message can be string, bytes, int32, float, double, and you check the rest of the supported types&nbsp;<a href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/proto3#scalar\" rel=\"noreferrer noopener\" target=\"_blank\">here<\/a>.<br>the number we specify after each property must be unique because it will represent the property name after the serialization process.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the&nbsp;<strong>service&nbsp;<\/strong>we specify the methods that we need to use in our service, we specify what input we need and what output will be produced from this method and the type of input and output is a&nbsp;<strong><em>message<\/em><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We have inside the service two methods one for creating an account which will take CreateAccountRequest as an input and return CreateAccountResponse.<br>The other one to get the account information which will take GetAccountInformationRequest as an input and return GetAccountInformationResponse.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ok, this is the definition but where I\u2019ll write my implementation? wait this will come next.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to compile this\u00a0file:<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>First: you have to install the compiler from&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/downloads\" target=\"_blank\">here<\/a>.<\/li><li>Goto the folder and write this command by using the Terminal:<br><code>protoc -I&nbsp;..\/account-proto --go_out=plugins=grpc:.\/proto-go&nbsp;..\/account-proto\/account.proto<\/code><\/li><li>After executing this command and hopefully without any errors you will find there a new file called&nbsp;<strong><em>account.pb.go<\/em><\/strong>&nbsp;which contain all the commands and the code that you will use to register and use this service, will also contain structs generated from our messages and also the service interface that we have to implement.<\/li><li>Then you create&nbsp;<strong><em>main.go<\/em><\/strong>&nbsp;and write this implementation.<br><\/li><\/ul>\n\n\n\n<pre class=\"line-numbers\" dir=\"ltr\"><code class=\"language-go\">package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"net\"\n\t\"errors\"\n\n\tpb \"github.com\/Ahmad-Magdy\/grpc-by-example\/proto-go\"\n\n\t\"google.golang.org\/grpc\"\n\t\"google.golang.org\/grpc\/reflection\"\n\t\"github.com\/satori\/go.uuid\"\n)\n\ntype Account struct {\n\tID       string\n\tUsername string\n\tEmail    string\n}\n\nvar (\n\taccounts []*Account\n)\n\ntype server struct{}\n\nfunc (s *server) CreateAccount(ctx context.Context, accountRequest *pb.CreateAccountRequest) (*pb.CreateAccountResponse, error) {\n\tfmt.Printf(\"Server: Recived, %s\\n\", accountRequest.GetUsername())\n\n\tnewAccount := &amp;Account{\n\t\tID: uuid.NewV4().String()  ,\n\t\tUsername: accountRequest.GetUsername(),\n\t\tEmail:    accountRequest.GetEmail(),\n\t}\n\n\taccounts = append(accounts, newAccount)\n\treturn &amp;pb.CreateAccountResponse{Id: newAccount.ID}, nil\n}\n\nfunc (s *server) GetAccountInformation(ctx context.Context, m *pb.GetAccountInformationRequest) (*pb.GetAccountInformationResponse,error){\n\t for _,accountItem:= range accounts{\n\t\t if accountItem.ID == m.GetId(){\n\t\t\t return &amp;pb.GetAccountInformationResponse{\n\t\t\t\t\t\t\t\t\t\t\tId:accountItem.ID, \n\t\t\t\t\t\t\t\t\t\t\tUsername : accountItem.Username, \n\t\t\t\t\t\t\t\t\t\t\tEmail:accountItem.Email, }, nil\n\t\t }\n\n\t }\n\t return nil, errors.New(\"account not found\")\n}\n\nfunc main() {\n\tlis, err := net.Listen(\"tcp\", \":3000\")\n\tif err != nil {\n\t\tlog.Fatal(\"Failed to listen: %v\", err)\n\t}\n\n\ts := grpc.NewServer()\n\tpb.RegisterAccountServiceServer(s, &amp;server{})\n\treflection.Register(s)\n\tif err := s.Serve(lis); err != nil {\n\t\tlog.Fatal(\"Failed to serve: %v\", err)\n\t}\n}\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let me explain what i have made here step by step:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1- I imported\u00a0<em>pb \u201cgithub.com\/Ahmad-Magdy\/grpc-by-example\/proto-go\u201d<\/em>\u00a0which contains the compiled proto file (\u201caccount.pb.go\u201d).<br>2- I defined a new struct called\u00a0<em>server<\/em>\u00a0which will contain the implementation of the methods we defined in the proto file.<br>3- We have two methods CreateAccount and GetAccountInformation so i created them.<br>4- I wrote a simple implementation of the two methods, it\u2019s not efficient or the best but it\u2019s enough to show you how it works.<br>5- Inside func main i created a new\u00a0<em>grpc server<\/em>\u00a0and register my service in it, the code of registering the service\u00a0<em>RegisterAccountServiceServer is autogenerated code from the compiled proto file that we defined.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Trying the\u00a0server:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">enough talking and let\u2019s try to run the server program.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"290\" src=\"https:\/\/magdy.dev\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-1024x290.png\" alt=\"\" class=\"wp-image-529\" srcset=\"https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-1024x290.png 1024w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-300x85.png 300w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-768x217.png 768w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-1920x543.png 1920w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-720x204.png 720w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-580x164.png 580w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run-320x91.png 320w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_console_go_run.png 2036w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">No error message, so everything is just fine \ud83c\udf89\ud83c\udf89.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The C#\u00a0part:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">let\u2019s go the client part in C# and create a new solution and project.<\/p>\n\n\n\n<pre class=\"line-numbers\" dir=\"ltr\"><code class=\"language-bash\">dotnet new sln --name xyz\ndotnet new classlib --name AccountServiceBase\ndotnet sln account-service-client.sln add AccountServiceBase\/AccountServiceBase.csproj\ncd AccountServiceBase\ndotnet add package Grpc\ndotnet add package Grpc.Tools\ndotnet add package Google.Protobuf\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We made a new solution then we created a new project as base which will contain the proto packages in C# and also the generated files from the proto file in C# format.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We have to include &lt;Protobuf&gt; as Item group the comiler the&nbsp;.proto file every time we build the project.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By the end of the process we should have csproj looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted line-numbers\" dir=\"ltr\"><code class=\"language-markup\"><\/code>&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;<br \/><br \/>&lt;PropertyGroup&gt;<br \/>&lt;TargetFramework&gt;netstandard2.0&lt;\/TargetFramework&gt;<br \/>&lt;\/PropertyGroup&gt;<br \/><br \/>&lt;ItemGroup&gt;<br \/>&lt;PackageReference Include=\"Google.Protobuf\" Version=\"3.6.1\" \/&gt;<br \/>&lt;PackageReference Include=\"Grpc\" Version=\"1.18.0\" \/&gt;<br \/>&lt;PackageReference Include=\"Grpc.Tools\" Version=\"1.18.0\"&gt;<br \/>&lt;IncludeAssets&gt;runtime; build; native; contentfiles; analyzers&lt;\/IncludeAssets&gt;<br \/>&lt;PrivateAssets&gt;all&lt;\/PrivateAssets&gt;<br \/>&lt;\/PackageReference&gt;<br \/>&lt;\/ItemGroup&gt;<br \/><br \/>&lt;ItemGroup&gt;<br \/>&lt;Protobuf Include=\"..\/..\/**\/*.proto\" OutputDir=\"%(RelativePath)\" CompileOutputs=\"false\" \/&gt;<br \/>&lt;\/ItemGroup&gt;<br \/><br \/>&lt;\/Project&gt;<br \/><br \/><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you run \u201cdotnet build\u201d you should be able to see two generated files, Account and AccountGrpc which we will use later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s create the actual client in the solutions\u2019 folder.<\/p>\n\n\n\n<pre class=\"line-numbers\" dir=\"ltr\"><code class=\"language-bash\">dotnet new console --name AccountServiceClient\ndotnet sln account-service-client.sln add AccountServiceClient\/AccountServiceClient.csproj\ndotnet add AccountServiceClient\/AccountServiceClient.csproj reference AccountServiceBase\/AccountServiceBase.csproj\n<\/code><\/pre>\n\n\n\n<pre class=\"line-numbers\" dir=\"ltr\"><code class=\"language-csharp\">static void Main(string[] args)\n{\n    var channel = new Channel(\"localhost:3000\", ChannelCredentials.Insecure);\n\n    var client = new AccountService.AccountServiceClient(channel);\n\n    var reply = client.CreateAccount(new CreateAccountRequest() {Username = \"Adam\",Email = \"a@amagdy.me\"});\n   \n    Console.WriteLine($\"Reply from the server with message {reply.Id}\");\n\n    channel.ShutdownAsync().Wait();\n}\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>We defined the Channel to connect to the server which we defined in go before with the same port \u201c:3000\u201d and we chose the Credentials to be Insecure and with that, it will be without SSL, you can read more about that from\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/grpc.io\/grpc\/csharp\/api\/Grpc.Core.ChannelCredentials.html#Grpc_Core_ChannelCredentials_Insecure\" target=\"_blank\">here<\/a>.<\/li><li>After that, we defined the client to our service.<\/li><li>We executed CreateAccount and waited for the response from the server.<\/li><li>All the models were created for us thanks to the proto compiler.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"289\" src=\"https:\/\/magdy.dev\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-1024x289.png\" alt=\"\" class=\"wp-image-531\" srcset=\"https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-1024x289.png 1024w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-300x85.png 300w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-768x217.png 768w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-1920x541.png 1920w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-720x203.png 720w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-580x164.png 580w, https:\/\/magdy.dk\/blog\/wp-content\/uploads\/2019\/06\/grpc_running_program-320x90.png 320w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this article, we learned about how to get started with gRPC, we learned about it by doing a small service in go and use it in C# which totally different language.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TODO: Share the project in Github.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><br><\/p><cite>This post was originally written for <a href=\"https:\/\/medium.com\/@ahmadmagdy\/grpc-in-action-ad3c8bb3e8a9\">Medium<\/a>.<\/cite><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will learn about gRPC and how we can use it by examples. First: What is&nbsp;gRPC? let\u2019s take part of the word first, RPC: stands for Remote Procedure Call and it\u2019s a mechanism used when you have client-server model in a shared network to transfer the data between the client and the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[6],"tags":[21,20,19,22,23,18],"class_list":["post-521","post","type-post","status-publish","format-standard","hentry","category-technology","tag-dotnet","tag-go","tag-golang","tag-grpc","tag-microservices","tag-protobuf"],"aioseo_notices":[],"views":794,"_links":{"self":[{"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/posts\/521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/comments?post=521"}],"version-history":[{"count":9,"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/posts\/521\/revisions"}],"predecessor-version":[{"id":540,"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/posts\/521\/revisions\/540"}],"wp:attachment":[{"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/media?parent=521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/categories?post=521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/magdy.dk\/blog\/wp-json\/wp\/v2\/tags?post=521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}