gRPC
What does it mean?
g | gRPC |
R | Remote |
P | Procedure |
C | Calls |
What is it used for?
- Client ⇔ Server Communication
- Server ⇔ Server Communication
- X ⇔ Y Communication
Transport channel ¯\(ツ)/¯
gRPC is agnostic about the transport channel.
For client server communication in a web application we use gRPC over HTTP.
Why use it rather than [X] ?
- Efficient serialization → Small message size
- Interface definition can easily be shared (.protobuf files)
- Support for both server-side code generation and client generation for many languages
- Integrating systems in different languages
Programming Model
A client application calls a method on a server application on a different machine as if it were a local object.
Multiple Different Clients
Message Format
By default gRPC uses Protocol Buffers
// This is how you define services and message types.
service Greeter { rpc SayHello (HelloRequest) returns (HelloReply);}
message HelloRequest { string firstName = 1; string lastName = 2;}
message HelloReply { string greeting = 1;}
Adding gRPC and Protobuf to a .NET Solution
You need three projects.
- Install NuGet Packages in Shared project:
Grpc.Net.ClientGoogle.ProtobufGrpc.Tools
- Add folder
Grpc
in Shared project - Add reward.proto file in that folder
syntax = "proto3";option csharp_namespace = "SavingsPlanner.Shared.Grpc";package Rewards;
service Rewards { rpc GetRewards (RewardRequest) returns (RewardReply);}
message RewardRequest {}
message RewardReply { repeated RewardItem rewards = 1;}
message RewardItem { int32 id = 1; string title = 2; double targetAmount = 3; string description = 4;}
Add code in Shared .csproj file
<ItemGroup> <Protobuf Include="Grpc/reward.proto" GrpcServices="Server,Client"> </Protobuf></ItemGroup>
- Install NuGet Packages in Client project:
Grpc.Net.Client.Web
// Add in Program.cs of client projectbuilder.Services.AddSingleton(services =>{ var httpClient = new HttpClient( new GrpcWebHandler( GrpcWebMode.GrpcWeb, new HttpClientHandler())); var baseUri = services .GetRequiredService<NavigationManager>() .BaseUri; var channel = GrpcChannel .ForAddress( baseUri, new GrpcChannelOptions { HttpClient = httpClient }); return new Rewards.RewardsClient(channel);});
// in a Blazor component on the client@inject Rewards.RewardsClient RewardsClient
private async Task LoadDataAsync(){ var rewardsResponse = await RewardsClient.GetRewardsAsync(new RewardsRequest()); rewards = rewardsResponse.Rewards.ToArray();}
- Install NuGet Packages in Server project:
Grpc.AspNetCore.WebGrpc.AspNetCore
- Implement a service by deriving from generated classes in Shared project (next slide)
public class RewardService : Rewards.RewardsBase{ private readonly IRepository<Reward> _repository; public override async Task<RewardReply> GetRewards( RewardRequest request, serverCallContext context) { var reply = new RewardReply(); var items = await _repository.GetAllAsync<RewardItem>(); reply.Rewards.AddRange(items); return reply; }}
// in Program.cs of Server projectbuilder.Services.AddGrpc();app.UseGrpcWeb();app.MapGrpcService<RewardService>().EnableGrpcWeb();
// Automapper configuration// for transformation to generated typeCreateMap<Reward, RewardItem>() .ForMember( r => r.TargetAmount, opt => opt.MapFrom(src => (double)src.TargetAmount));