How to make your first gRPC application with C# .Net. Fast! 2


grpc

In this post we are going to look at gRPC, What is it? Why would you use it? How is it different from a standard Rest API endpoint. Then finally we are going to create a simple app using gRPC.

What is gRPC?

gRPC is a modern open source high performance Remote Procedure Call (RPC) framework that can run in any environment. see: grpc.io

What is RPC?

remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network) see: rpc

Why use it?

So gRPC which is googles installment of RPC. Allows a client application to execute predefined code on the server. Another key point about gRPC is that it works with Http/2 to allow bidirectional streaming of data. That coupled with the fact that it allows for binary sterilization. Makes things small and fast.

How is it different from a standard rest api endpoint?

Rest transferer is different in that it is not streaming. You send a request normally as HTTP POST or HTTP GET. data format is normally in XML or JSON.

Lets make a gRPC calculator.

As you know I am a freelance application developer. I had a client which is in the process of porting some of his application over to microservices. There are serval parts of their application which would lend themselves nicely to gRPC file uploading for example. This was not the first time that I have created a gRPC system for a clinet, but it was the first time that I got to see first hand the power and ease of development with these kinds of systems.

Lets create a very simple application. I have created two console applications a client and a server. Both of these applications will need to have a proto directory. In this directory we are going to create a file.

calculator.proto

When working with protocol buffers the first thing we do is define the proto file. This file will define the structure for our data. In this example we define the Calculator service object and the methods it will support, then we define the MathResult and the MathRequest objects.

syntax = "proto3";

option csharp_namespace = "GrpcService1";

package Calculator;

enum MathType
{  
  Add = 0;
  Subtract = 1;
}

// The Math service definition.
service Calculator {  
  rpc GetAnswer( MathRequest) returns ( MathResult) {}
}

// The request message containing the user's name.
message MathRequest {
  MathType type = 1;
  int32  one = 2;
  int32  two = 3;
}

message MathResult {
  int32 answer = 1;
}

If you were creating a standard web api endpoint with ASP .net you would probably have a Calculator controller with a POST endpoint for GetAnwser.

Checking your .csprog file

I use JetBrains rider for my development IDE. In my experience when adding the .proto file to my project Rider does some interesting things to the underlying .csprog file. I have reported this issue When adding proto file Rider adds extra stuff to .csprog that does not always work and is just ugly (IMO). So I always check the file, you will need to check it anyway to define which type of GrpcServices you are defining with in the project.

For your client project you should have something like this

<ItemGroup>
    <Protobuf Include="Protos\calculator.proto" GrpcServices="Client" />
</ItemGroup>

then for your server project you should have something like this

<ItemGroup>
<Protobuf Include="Protos\calculator.proto" GrpcServices="Server" />
</ItemGroup>

Notice how the GrpcServices changes depending upon the type of project. Pro tip: if your going to have a service and a client in the same project you should use the term Both

<ItemGroup>
    <Protobuf Include="Protos\calculator.proto" GrpcServices="Both" />
</ItemGroup>

If you are using Both I would love to hear your use case please comment below.

CalculatorService.cs

Our server project will need to have a CalculatorService defined, which inherits from Calculator.CalculatorBase. The wonderful thing about using gRPC is that most of these methods have been built for you. So when adding the GetAnwser method and overriding it. The easiest way to find the error is just to check the source on what we are inheriting from it will show you exactly what your return types need to be. In this case we our method takes a MathRequest which we defined in the .proto file and it returns a MathResult.

public class CalculatorService : Calculator.CalculatorBase
{
private readonly ILogger<GreeterService> _logger;

public CalculatorService(ILogger<GreeterService> logger)
{
_logger = logger;
}

public override Task<MathResult> GetAnswer(MathRequest request, ServerCallContext context)
{
var result = 0;
if (request.Type.Equals(MathType.Add))
{
result = request.One + request.Two;
}
else
{
result = request.One - request.Two;
}

var data = new MathResult()
{
Answer = result
};

return Task.FromResult(data);
}
}

Everything else was already created for us.

Registering in DI

In our program.cs file on the server we will need to register the CalculatorService

The first thing we do is add Grpc to our project, followed by adding our service.

// Add services to the container.
builder.Services.AddGrpc();
app.MapGrpcService<CalculatorService>();

That is all our calculator server project should now be up and running.

The Client

Believe it or not the client is even easer. We configure our channel with the location of the server.

var channel = GrpcChannel.ForAddress("https://localhost:7250");

Create our client

// Math
var clientMath = new Calculator.CalculatorClient(channel);

Then call the method

var mathResult =  clientMath.GetAnswer(new MathRequest() { Type = MathType.Add, One = 1, Two = 2});
Console.WriteLine(mathResult.Answer);

Its really that simple.

Conclusion

I believe whole heartedly that gRPC has its place in our systems. They are faster to develop, and easer to support. I hope I will be helping clients create more systems using gRPC in the future they are a joy to work with and create.


About Linda Lawton

My name is Linda Lawton I have more than 20 years experience working as an application developer and a database expert. I have also been working with Google APIs since 2012 and I have been contributing to the Google .Net client library since 2013. In 2013 I became a a Google Developer Experts for Google Analytics.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 thoughts on “How to make your first gRPC application with C# .Net. Fast!

  • Rasmus

    If this was a real application I guess you would have an interface for the CalculatorService, and not a service itself in your MapGrpcService call.

    For simple calls, do you get any performance benefits?

    Is it possible to have your proto file generated based on your service and then expose it?

    • Linda Lawton Post author

      From my understanding we need the proto file to create the service. So no I don’t think you can do it the other way.

      I need to find some time to do some bench marking but the issue is what to bench mark.