SHARE:

gRPC & ASP.NET Core 3.1: What’s gRPC-web & how to create a gRPC-web service ?

What’s gRPC-web ?

In the summer of 2016, both a team at Google and  Improbable independently started working on implementing something that could be called “gRPC for the browser”. They soon discovered each other’s existence and got together to define a spec for the new protocol.

It is currently impossible to implement the HTTP/2 gRPC spec in the browser, as there is simply no browser API with enough fine-grained control over the requests. For example: there is no way to force the use of HTTP/2, and even if there was, raw HTTP/2 frames are inaccessible in browsers. The gRPC-web spec starts from the point of view of the HTTP/2 spec, and then defines the differences. These notably include:

  • Supporting both HTTP/1.1 and HTTP/2.
  • Sending of gRPC trailers at the very end of request/response bodies as indicated by a new bit in the gRPC message header.
  • A mandatory proxy for translating between gRPC-web requests and gRPC HTTP/2 responses.

Note that gRPC-web is not compatible with client-side and bi-directional streaming but only with unary and server-side streaming.

Source: https://grpc.io/blog/state-of-grpc-web/

Envoy can be used as the mandatory proxy:

Because Improbable implementation supports TypeScript, I chose this library to make the demo in the next article, here is the link of Improbable gRPC-web repository: https://github.com/improbable-eng/grpc-web

gRPC-web & ASP.NET Core 3.1

In january 2020, Microsoft has announced an experimental support for gRPC-web with ASP.NET Core. Compatible with browsers (like Angular, React apps and more SPAs), Blazor WebAssembly and even Xamarin, that implementation brings an important feature: the uselessness of using a proxy such as Envoy.

To learn more about Microsoft announcement you can read this article: https://devblogs.microsoft.com/aspnet/grpc-web-experiment/

Implementation of gRPC-web & ASP.NET Core 3.1

We’ll need to download that preview package in your ASP.NET Core 3 project:

 Install-Package Grpc.AspNetCore.Web -Version 2.28.0-pre2

In our Startup. cs we will add the required config:

Configure CORS policies in ASP.NET Core 3

gRPC-web requires CORS.

  • Origins must be set with our known domains (such as localhost and our official domain name on internet)
  • Methods allowed must be POST and depending the browser OPTIONS too
  • All Request headers must be allowed
  • Response headers (exposed headers) must allow Grpc-Status and Grpc-Message

Activate gRPC-web middleware

The middleware app.UseGrpcWeb() must be activated. Its role is to catch requests that ask a gRPC endpoint to answer a non binary answer then text instead in order to be compatible with the browser, there are 2 types of Content-Type:

  • application/grpc-web which is compatible with unary services
  • application/grpc-web-text which is compatible with unary and server-side streaming services

Apply Cors and enable gRPC-web on services

This is the last step, we need to apply Cors and gRPC-web on services: .MapGrpcService<CountryGrpcService().RequireCors(“MyPolicy”).EnableGrpcWeb();

gRPC-web can be enabled for all services by adding this line in ConfigureServices: services.AddGrpcWeb(o => o.GrpcWebEnabled = true); so you don’t need to add on each service .EnableGrpcWeb();

The Startup.cs file should look like this:

For more information you can go to the Microsoft documentation: https://docs.microsoft.com/en-us/aspnet/core/grpc/browser?view=aspnetcore-3.1

Azure App Service support

Good news! Unlike gRPC, gRPC-web in ASP.NET Core 3 is supported by Azure App Services.

The thing you need to know is that Azure App Services doesn’t support HTTP/2 then you have to deploy your app with HTTP/1 as Kestrel default end points protocol settings in the appsettings.json file.

If you keep HTTP/2 in your settings, it will only work on Windows App Services because this one runs with module named ASPNetCoreModuleV2 that makes sure the app works fine on Windows (turns HTTP/2 to HTTP/1). On Linux App Services the docker behind the scene will fail on start:

Conclusion

We saw how to make gRPC compatible with browsers with a new spec: gRPC-web. The ASP.NET Core implementation of gRPC-web is still in preview, there is no commitment from Microsoft from now on this.

In the next article we will how to consume an gRPC-web service with an Angular 8 app and also with console app using HttpClient.

Written by

anthonygiretti

Anthony is a specialist in Web technologies (14 years of experience), in particular Microsoft .NET and learns the Cloud Azure platform. He has received twice the Microsoft MVP award and he is also certified Microsoft MCSD and Azure Fundamentals.