Last week I started investigating gRPC in a post called It’s All About Communication…Application Communication. There I started to look into gRPC. In this post I want to start playing with it. If you got check out the official gRPC site you will find some really good documentation including examples. The instruction for these examples include "clone the repository, navigate to your language’s example folder and run it". This is cool because it is instant payoff proving that the most basic example works and believe me they are basic…Hello World! I needed to investigate how I would add this to an existing project. So I decided to do File -> New Project to gain an understanding of the pieces needed.
As you will see I first created a new .Net Core class library. I then I added some gRPC dependencies. After adding the dependencies, one of the things I notices was that there was very little tooling support for working with gRPC in Visual Studio. I checked to see if there was a Visual Studio extension that may add some support. There is an extension called Protobuf Language Service that supports Google’s protobuf definitions within Visual Studio. The only problem is it was written 4 years ago for VS2017 and has not been touched since, which means no VS2019 support. So keep that in mind when you start developing with gRPC.
Here we go "File -> New Project"
I am going to create a simple calculator service that takes 2 integers and adds them together returning the results. Start out by creating a .Net Core Library project. This is where we will define our service interfaces and messages. At this point you can delete the Class.cs file from this project. We won’t be using that. The first thing we need to do is reach out to NuGet and get the 3 packages we will need for our simple example. They are Grpc, Grpc.Core andGoogle.Protobuf. There are more Grpc libraries but we will not need them for this example but feel free to investigate what they offer…believe me I will be. Let’s finish up the steps for creating the service definition.
- Create a .Net Core Library Project
- Add a text file to the project, name it what you will and change the extension to be .proto. Proto files are written in Protocol Buffer syntax. We will only be covering the very basics here. You can find detailed explanations in the Proto Language Guide (proto3).
- Change the Build Action on your .proto file to "Protobuf Compiler". This was added when you added the dependencies and is what generates the needed classes from the proto file. NOTE: If you are using VS2019 you may need to restart VS after installing the dependencies to see this option.
- Inside the .proto file we have to define which version of the Protocol Buffer syntax we want to use. The current version is 3 but 2 is still available. Version 1 was in the private days of gRPC, before it was released to the public.
- Next we define the methods we want to expose. Here we are defining one but we can define as many as we need. Think of this as the service interface.
- Now define the request message. This is the object that will be used to pass data to the service.
- Do the same for the reply message.
- Build the project.
After you build the project you will see….nothing. Show hidden files and navigate to "obj -> Debug -> .Net Version. You will see some files that were generated for you. These files are contain all the things you will need to send and receive messages through gRPC.
Now it is time to create the server that will be hosting the implementation of the service interface defined in the proto file.
- Add a .Net Core Console application to the solution.
- Add a project reference to the class library we created in the last step.
- Create a class that will implement the interface. I called mine Calculator.cs
- When you built the class library it generated a base class for the service. Your implementation class needs to inherit from that base class.
- Over ride the service method that is in that base class. NOTE: There will be a synchronous and asynchronous versions of the method. So both are available. Override the one you want to implement.
- Implement the server in the Program.cs file’s Main method.
- Define the port you want your service to listen on.
- Create a Server object. NOTE: The Services property is a collection of implementation bindings so there can be more than 1. Also Ports is a collection of ports to listen on.
- Start the server.
Put a read line in there so that the service stay running. This is fine for our example but you may want to host it in something like Kestral in the real world.
We have a server, now we need something to call it. Remember from my last post the client does not need to be written in the same language as the server. There are compilers for different languages that will compile the .proto file in to code that can be in used by those different languages.
- Add a .Net Core Console application to the solution.
- Add a project reference to the service class library.
- Implement the client code In the Main method of the Program.cs file.
- Create a channel for the client to call out. NOTE: The second parameter of the Channel constructor deals with how to secure the channel I am not covering that in this blog but know that it is there.
- Create a client using the channel you created above.
- Call the method on the service, creating a new request object (auto generated from the message in the proto file)
- Display the response from the service. NOTE: The response is the response message from the proto file.
Run the Code
That is all there is to it. You have defined the service, created a server and created a client. You can now run the code. Start the server first. Once it is listening, then start the client. You should see output that looks like the following:
There it is, a simple example of how to get a gRPC service up and running from scratch. If your really want to start without having to write it yourself you can get my code Here. So what’s next? One of my requirements is that my services have to run in Docker. So I will get that working and report back.