TECH Insights

Viden og indsigter fra IT Minds' it-talenter

gRPC in ASP.NET Core 3.0

Skrevet af Mindster og Software Developer hos IT Minds on 03-10-19 10:43
Mindster og Software Developer hos IT Minds

Alongside .Net Core 3.0 comes a welcome feature to the ASP.NET Core framework, more precisely the support for using gRPC (Google Remote Procedure Calls).

gRPC is a RPC (Remote Procedure Calls) framework, and was made open source by Google back in 2015, so as you might have noticed the technology isn't new. But it's new in ASP.NET Core. The communication is done over the http2 protocol (see a brilliant introduction to http2 here).

Why is it cool?

Firstly; it's fast, very fast. It relies on binary serialization instead of a human readable JSON format, it makes the package size considerably smaller reducing the network overhead.

Secondly; it has a idiomatic service definition language, meaning that when you have specified your services you can generate server stubs or clients in 10 different programming languages. This offers immense flexibility in systems with a microservice architecture because all of your services doesn't have to be written in the same language/framework as long as it adheres to the specification.

Thirdly; the framework supports bidirectional streaming over http2, meaning that the client can stream its request to the server and the server can stream responses to its clients. This enables processing of the received data while the transfer is still going, i.e. you might need to upload a lot of images to the server at once, but would like the server to compress and save the images as it receives them.

It is "often" used in microservice architectures as the communication framework of choice in between services, often an API Gateway is implemented to mitigate communication with end clients via a RESTful JSON API. This is in part due to the lacking http2 support on client machines.

<TL;DR>

It has a lot of nifty features, is very flexible, allows rapid prototyping and is blazing fast compared to RESTful APIs using JSON.

Show me the code

After downloading and installing the .NET Core 3.0.1 SDK a new project template will be available through dotnet new,

We will scaffold our gRPC service with the following CLI command:

Screenshot 2019-10-03 at 10.29.19

This will scaffold an ASP.NET Core web project for you with a folder called Protos. This is the idiomatic service definition mentioned above.

Let's take a look at the service definition that was generated. This is a so called protobuf (Protocol Buffers) definition:

Screenshot 2019-10-03 at 10.31.05

This is a simple example of a service called GreeterService. The service has one method called SayHello. The method receives a HelloRequest containing a name to greet, and returns a HelloReply greeting the name specified in the request.
Please note that all the fields in the Request and the Reply is numbered. This is to ensure that the object is deserialized correctly. The numbers must be unique and shouldn't be changed once a service is in use. If a field is removed the number dies with it. New fields should also have new uniquenumbers.

Fields can be made made required, optional and repeated. Repeated fields can be repeated any number of times including zero i.e. it is used for collections of objects.

When you build this project, a stub for the service is generated. This stub is used to implement the actual service. Let's take a look at the default implementation of our GreeterService. 

Screenshot 2019-10-03 at 10.32.46

As you can see the service inherits Greeter.GreeterBase. This is the Service stub that was generated during build. The stub is generated from the proto file we just took a look at. In this case it has made a service stub and the corresponding Requests and Responses.

Working with streams

As I mentioned earlier the gRPC framework allows for bidirectional streaming of requests/responses. The default example doesn't include any streaming operations, lets make one.
First lets modify our proto file to include a streaming request. In this case we will add a new method StreamHello that streams the response as a stream of charts instead of a string.

I've modified my proto file to include a method that streams the response, and added a new response type containing a single character instead of the entire message.

Screenshot 2019-10-03 at 10.33.39

After modifying our service to include a streaming endpoint it looks like this:

Screenshot 2019-10-03 at 10.35.43-1

To see the full code snippet visit: https://dev.to/itminds/grpc-in-asp-net-core-3-0-pm 

The functionality in the stream endpoint StreamHello is rather pointless, it only serves to be a simple example of the stream implementation.

Enabling gRPC in Startup

To enable the gRPC endpoints we need to add a few things to our Startupclass. The scaffolded project already contains these lines, but I'll highlight them here in case you need to include a gRPC service in an existing web project.

Firstly we need to modify our ConfigureServices method:

Screenshot 2019-10-03 at 10.37.07

Second we need to modify our Configure method:

Screenshot 2019-10-03 at 10.37.51

To see the full code snippet visit: https://dev.to/itminds/grpc-in-asp-net-core-3-0-pm 

The client side of things

A client for your gRPC service can be implemented in many different languages/frameworks. A list of languages can be found on the gRPC homepage grpc.io

For simplicity reasons we will create our client as a dotnet core console app. We do that by running the following:

Screenshot 2019-10-03 at 10.38.33

This scaffolds an ASP.NET Core console application with the required nuget packages for making gRPC communication.

We need our proto definition to ensure the client, we generate adhere to the service definition. We create a folder in our client application called Protosand copy the proto definition from earlier into this new folder.

After copying the proto file we need to add the following xml to our project file in the client project:

Screenshot 2019-10-03 at 10.39.58

Now when we build our client project the Greeter namespace stubs will be generated as we did in our service project. After generating the client part of the library we added some business logic to our Program.cs. See below:

Screenshot 2019-10-03 at 10.41.01

Running the code produces the following output:

Screenshot 2019-10-03 at 10.41.54

Conclusion

This has been a brief look into what it takes to get gRPC up and running in ASP.NET Core 3.0 - there's still a lot more to learn.
The protobuf definition language contains a lot of small caveats (reserved field numbers, field number size allocation, etc...) and neat tricks to precisely specify the behavior of the service.

Furthermore the client and server stubs can be generated in a lot of different languages (C++, C#, Ruby, Go, node.js, PHP and many more...).

All source code used in this blog post can be found on GitHub.

Inspiration/Further reading

Articles, guides and tutorials i read before writing this blog post:

Insights fra de bedste softwaretalenter

En del af IT Minds’ DNA er, at vi spotter og tiltrækker de bedste softwaretalenter, som er stærke i de nyeste teknologier og frameworks. Derfor vil vi gerne dele ud af vores viden og erfaringer vores konsulenter opsamler, når de afprøver og arbejder med nye teknologier og frameworks.

Seneste indlæg