- Published on
- 🍵 5 min read
gRPC in .NET
- Authors
- Name
- Emin Vergil
- @eminvergil
Overview
- Target Audience
- Learning Objectives
- What is gRPC ?
- Example workflow in dotnet
- Create a gRPC dotnet service
- Example code
- Benefits
- Call gRPC services with the .NET client
- How can we make a call from client ?
- Envoy
Target Audience
I've aimed this article at people who want to learn using gRPC in dotnet
Learning Objectives
After completing this article, you will know how to do the following:
- Create a simple gRPC dotnet application
- Benefits of gRPC
- Create a gRPC service
What is gRPC ?
gRPC (gRPC Remote Procedure Calls) is an open-source framework designed by Google for building efficient, scalable, and high-performance APIs and microservices.
Here are the key features and concepts of gRPC:
Protocol Buffers: gRPC uses Protocol Buffers (protobufs) as its interface definition language (IDL) for defining the structure of the data and service interfaces. Protobufs are a language-agnostic, platform-neutral extensible mechanism for serializing structured data, similar to XML or JSON but smaller, faster, and simpler.
High Performance: gRPC supports HTTP/2, providing significant performance improvements over traditional HTTP/1.1, including multiplexing multiple requests over a single connection, header compression, and server push.
Cross-Platform: gRPC supports a wide range of programming languages. This makes it suitable for building cross-platform applications and services.
Bi-Directional Streaming: gRPC supports multiple types of streaming:
- Unary: Single request and single response.
- Server Streaming: Single request followed by a stream of responses.
- Client Streaming: Stream of requests followed by a single response.
- Bi-Directional Streaming: Streams of requests and responses simultaneously.
Pluggable Authentication: gRPC supports pluggable authentication mechanisms, such as SSL/TLS for encryption and OAuth tokens for authorization, ensuring secure communication between clients and servers.
Load Balancing and Name Resolution: gRPC provides built-in support for load balancing and service discovery, making it easier to manage microservices architectures.
Code Generation: gRPC uses the protobuf compiler (protoc) to generate client and server code in various programming languages, enabling developers to quickly implement services without writing boilerplate code.
Example workflow in dotnet
- Define service and messages in a
.proto
file. - Implement the generated service methods
Create a gRPC dotnet service
you can use --list
keyword to list all of the templates that you can create.
dotnet new --list
to create a gRPC service use the following command:
dotnet new grpc -o my-grpc-service
As you can see from the example project all you need to do is define a protobuf, include the Grpc.AspNetCore
package and implement the methods.
Example code
syntax = "proto3";
option csharp_namespace = "remove_grpc_service";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
Here is an example for the implementation of greet.proto
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
you also need to enable http2 for kestrel.
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
example Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<GreeterService>();
app.Run();
Benefits
- High Performance: Efficient serialization with Protocol Buffers ensures low-latency communication.
- Bi-Directional Streaming: Supports real-time, two-way data streams between client and server.
- Cross-Platform: Provides strong support for multiple programming languages, enhancing versatility.
- HTTP/2 Support: Leverages HTTP/2 features like multiplexing and compression for better performance.
- Automatic Code Generation: Simplifies development by generating client and server code from protobuf definitions.
Call gRPC services with the .NET client
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var greeterClient = new Greet.GreeterClient(channel);
var counterClient = new Count.CounterClient(channel);
// Use clients to call gRPC services
How can we make a call from client ?
If you want to make a api call from web application you can use a proxy server to handle this process or you can use json transcoding for dotnet.
Envoy
Currently, browser api doesn't support gRPC on the client-side. We can use Envoy server to handle this issue.
Envoy can be used as a proxy server and it has built-in support for gRPC.
Here is an example yaml file for envoy proxy to handle grpc
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8000 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ['*']
routes:
- match: { prefix: '/' }
route:
cluster: greeter_service
max_stream_duration:
grpc_timeout_header_max: 0s
cors:
allow_origin_string_match:
- prefix: '*'
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: '1728000'
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.filters.http.grpc_web
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.cors
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.router
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: greeter_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
load_assignment:
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: grpc_server_service
port_value: 50051