Introduction
In this article we will look at gRPC and how to implement gRPC solutions using Visual Studio 2019. gRPC is a high performance, open-source and easy to use RPC framework developed by Google. It has gained lots of popularity as it can be used across platforms and has lots of features for easy documentation. Visual Studio 2019 includes a template for building gRPC server applications, and we will look at building a simple gRPC server application. We will also build a client application to consume the API that is available on the server.
Difference between gRPC and Web API
One question that might come to mind immediately is, what is the difference between Web API of the .NET world and gRPC of the Google world. Although both are cross platform and open source the main difference is that requests for Web API are in a text format which are human readable whereas gRPC messages are encoded by Protobuf by default. Protobuf or Protocol buffers is a very efficient way to transfer information and the binary format is not human readable.
Building the gRPC server
We will be using Visual Studio 2019 to build the gRPC server. Create a new project and follow the steps below,
You can delete the existing “greet.proto” file and the service associated with it. Then add the following employee.proto file to the Protos folder,
- syntax = "proto3";
-
- option csharp_namespace = "GrpcEmployee";
-
- package employee;
-
-
- service Employee {
-
- rpc GetEmployeeInfo (EmployeeInfoRequest) returns (EmployeeInfoResponse);
- }
-
-
- message EmployeeInfoRequest {
- int32 ID = 1;
- }
-
-
- message EmployeeInfoResponse {
- int32 ID = 1;
- string FirstName = 2;
- string LastName = 3;
- string Address = 4;
- string PhoneNumber = 5;
- string EmailAddress = 6;
- }
Ensure that the property settings of this file are as below,
Also, add a class “EmployeeService” under services as below,
- using System.Threading.Tasks;
- using Grpc.Core;
- using Microsoft.Extensions.Logging;
-
-
- namespace GrpcEmployee
- {
- public class EmployeeService : Employee.EmployeeBase
- {
- private readonly ILogger<EmployeeService> _logger;
- public EmployeeService(ILogger<EmployeeService> logger)
- {
- _logger = logger;
- }
-
- public override Task<EmployeeInfoResponse> GetEmployeeInfo(EmployeeInfoRequest request, ServerCallContext context)
- {
- return Task.FromResult(new EmployeeInfoResponse
- {
- ID = 100,
- FirstName = "John",
- LastName = "Doe",
- Address = "Toronto",
- PhoneNumber = "123-123-1234",
- EmailAddress = "[email protected]"
- });
- }
-
- }
- }
Ensure the project file matches the below,
- <Project Sdk="Microsoft.NET.Sdk.Web">
-
- <PropertyGroup>
- <TargetFramework>netcoreapp3.1</TargetFramework>
- </PropertyGroup>
-
- <ItemGroup>
- <Protobuf Include="Protos\employee.proto" GrpcServices="Server" />
- </ItemGroup>
-
- <ItemGroup>
- <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
- </ItemGroup>
-
- </Project>
You can now build and run the application and you will see the below,
Building the gRPC client
We will now build the client application which will call the API on the gRPC server. This will be a simple .NET Core 3.1 console application.
Create a folder called “Protos” and add the below employee.proto file to it as below,
- syntax = "proto3";
-
- option csharp_namespace = "GrpcEmployee";
-
- package employee;
-
-
- service Employee {
-
- rpc GetEmployeeInfo (EmployeeInfoRequest) returns (EmployeeInfoResponse);
- }
-
-
- message EmployeeInfoRequest {
- int32 ID = 1;
- }
-
-
- message EmployeeInfoResponse {
- int32 ID = 1;
- string FirstName = 2;
- string LastName = 3;
- string Address = 4;
- string PhoneNumber = 5;
- string EmailAddress = 6;
- }
The properties of this file are as below,
Add the below code to the Main function,
- using System;
- using System.Threading.Tasks;
- using GrpcEmployee;
- using Grpc.Net.Client;
-
- namespace GrpcClient
- {
- class Program
- {
- static async Task Main(string[] args)
- {
-
- using var channel = GrpcChannel.ForAddress("https://localhost:5001");
-
- var client = new Employee.EmployeeClient(channel);
- var reply = await client.GetEmployeeInfoAsync(
- new EmployeeInfoRequest { ID = 100 });
-
- Console.WriteLine(reply);
-
- Console.WriteLine("Press any key to exit...");
- Console.ReadKey();
- }
- }
- }
Also, ensure the project file matches the below,
- <Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>netcoreapp3.1</TargetFramework>
- </PropertyGroup>
-
- <ItemGroup>
- <PackageReference Include="Google.Protobuf" Version="3.11.4" />
- <PackageReference Include="Grpc.Net.Client" Version="2.28.0" />
- <PackageReference Include="Grpc.Tools" Version="2.28.1">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
- </PackageReference>
- </ItemGroup>
-
- <ItemGroup>
- <Protobuf Include="Protos\employee.proto" GrpcServices="Client" />
- </ItemGroup>
-
- </Project>
Here we see that three NuGet packages have been added.
We can now run the client application and we see that it communicates with the gRPC server and returns the data.
Summary
In this article, we have looked at how to create a gRPC server and then create a client application to consume the API from this server. This is a useful API to understand in addition to the Web API from the Microsoft world. It will give you more options when you are in the process of developing a RPC framework.