How to Utilize gRPC-Web From a Blazor WebAssembly Application

Wael Kdouh
Jun 19 · 4 min read

Its no secret by now that there has been a lot of excitement about gRPC recently in the .Net community. gRPC is a modern high-performance RPC (Remote Procedure Call) framework. It is based on HTTP/2, Protocol Buffers and other modern standard-based technologies. It is also an open standard and is supported by many programming languages, including .NET.

It is currently impossible to implement the gRPC HTTP/2 spec in the browser because there are no browser APIs with enough fine-grained control over requests. Well the good news is that gRPC-Web is here for the rescue!!!

gRPC-Web is a standardized protocol that solves this problem and makes gRPC usable in the browser. gRPC-Web brings many of gRPC’s great features, like small binary messages and contract-first APIs, to modern browser apps. In this post I will demonstrate consuming a gRPC-Web endpoint from within a Blazor WebAssembly application. Along the way I will also demonstrate how gRPC-Web can achieve more efficient payload sizes compared to Restful endpoints.

The source code is hosted on my Github repository which can be found here.


The Solution

The solution I provided includes three projects. The Blazor WebAssembly project is the front end which will consume both a gRPC-Web endpoint as well as Restful endpoint.

Adding a gRPC-Web Endpoint

In order to add a gRPC-Web endpoint you actually have to start by adding a regular gRPC project.

gRPC Template in Visual Studio 2019

gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC. gRPC-Web does not require any changes to services. The only modification is startup configuration.

To enable gRPC-Web with an ASP.NET Core gRPC service follow the instructions included in the documentation here.

Consuming The gRPC-Web Endpoint From Blazor

Similar to consuming a Restful endpoint, you will need to register the gRPC-Web service in the service container inside the Program.cs file. The service creates a channel with a GrpcWebHandler that is addressed to the backend server.

Register the gRPC-Web Service

Note: The GrpcWebMode was set to GrpcWeb. It is recommended to stick with this mode (vs. GrpcWebText) if you are not doing any server streaming calls as it leads to reductions of of the message size upwards of 30%. More information can be found here.

Next I had to copy the Proto files from the Server project into the Blazor project and generate the client stubs (right click on the Proto file and click properties).

Note: You can improve the solution by storing the Proto files in a centralized location to be consumed by both the client and server applications.

Properties Window for a Proto file

Note: You need to install the Grpc.Tools nuget package in order to get the above window. For sake of completion I am sharing all the nuget packages I had to install within the Blazor WebAssembly project to consume the gRPC-Web endpoint.

Nuget Packages required to consume a gRPC-Web endpoint within a Blazor WebAssembly application

Now that I have all the settings in place to communicate with a gRPC-Web endpoint its time to wire the Blazor component to consume it. The following code shows the FetchData component consuming a gRPC-Web endpoint.

FetchDataGrpc.razor

For comparison, here is the same component consuming a Restful implementation of the same service.

FetchDataRest.razor

Note: In the case of FetchDataGrpc.razor the WeatherForecast model is automatically generated from the Proto file. gRPC services require a service contract usually defined using the Protocol Buffer Language in Proto files. The service contract is then used to generate your C# (or language of your choice) server-side classes and your client side proxies

The Results

Finally, the moment of truth. Does gRPC-Web delivers the promised optimizations compared to Restful endpoints as a result of using a binary format instead of JSON? Well I am happy to share that the answer is a yes. Here is the result of running the application with two components hitting both types of services and returning the same data. As you can see the gRPC-Web endpoint sends 427 Bytes compared to Rest’s 655 Bytes. I imagine the savings will be more pronounced when you send large amounts of data.

The WeatherData payload size sent from both a gRPC-Web and Rest endpoints

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store