January 27th, 2020

A new experiment: Call .NET gRPC services from the browser with gRPC-Web

James Newton-King
Principal Software Engineer

I’m excited to announce experimental support for gRPC-Web with .NET. gRPC-Web allows gRPC to be called from browser-based apps like JavaScript SPAs or Blazor WebAssembly apps.

gRPC-Web for .NET promises to bring many of gRPC’s great features to browser apps:

  • Strongly-typed code-generated clients
  • Compact Protobuf messages
  • Server streaming

What is gRPC-Web

It is impossible to implement the gRPC HTTP/2 spec in the browser because there is no browser API with enough fine-grained control over HTTP requests. gRPC-Web solves this problem by being compatible with HTTP/1.1 and HTTP/2.

gRPC-Web is not a new technology. There is a stable gRPC-Web JavaScript client, and a proxy for translating between gRPC and gRPC-Web for services. The new experimental packages allow an ASP.NET Core gRPC app to support gRPC-Web without a proxy, and allow the .NET Core gRPC client to call gRPC-Web services. (great for Blazor WebAssembly apps!)

New opportunites with gRPC-Web

  • Call ASP.NET Core gRPC apps from the browser – Browser APIs can’t call gRPC HTTP/2. gRPC-Web offers a compatible alternative.
    • JavaScript SPAs
    • .NET Blazor Web Assembly apps
  • Host ASP.NET Core gRPC apps in IIS and Azure App Service – Some servers, such as IIS and Azure App Service, currently can’t host gRPC services. While this is actively being worked on, gRPC-Web offers an interesting alternative that works in every environment today.
  • Call gRPC from non-.NET Core platforms – Some .NET platforms HttpClient doesn’t support HTTP/2. gRPC-Web can be used to call gRPC services on these platforms (e.g. Blazor WebAssembly, Xamarin).

Note that there is a small performance cost to gRPC-Web, and two gRPC features are no longer supported: client streaming and bi-directional streaming. (server streaming is still supported!)

Server gRPC-Web instructions

If you are new to gRPC in .NET, there is a simple tutorial to get you started.

gRPC-Web does not require any changes to your services, the only modification is startup configuration. To enable gRPC-Web with an ASP.NET Core gRPC service, add a reference to the Grpc.AspNetCore.Web package. Configure the app to use gRPC-Web by adding AddGrpcWeb(...) and UseGrpcWeb() in the startup file:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();
}

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();

    // Add gRPC-Web middleware after routing and before endpoints
    app.UseGrpcWeb();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb();
    });
}

Some additional configuration may be required to call gRPC-Web from the browser, such as configuring the app to support CORS.

Client gRPC-Web instructions

The JavaScript gRPC-Web client has instructions for setting up a gRPC-Web client to use in browser JavaScript SPAs.

Calling gRPC-Web with a .NET client is the same as regular gRPC, the only modification is how the channel is created. To enable gRPC-Web, add a reference to the Grpc.Net.Client.Web package. Configure the channel to use the GrpcWebHandler:

// Configure a channel to use gRPC-Web
var handler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
    {
        HttpClient = new HttpClient(handler)
    });

var client = Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new GreeterRequest { Name = ".NET" });

To see gRPC-Web with .NET in action, take a moment to read a great blog post written by Steve Sanderson that uses gRPC-Web in Blazor WebAssembly.

Try gRPC-Web with ASP.NET Core today

Preview packages are on NuGet:

Documentation for using gRPC-Web with .NET Core can be found here.

gRPC-Web for .NET is an experimental project, not a committed product. We want to test that our approach to implementing gRPC-Web works, and get feedback on whether this approach is useful to .NET developers compared to the traditional way of setting up gRPC-Web via a proxy. Please add your feedback here or at the https://github.com/grpc/grpc-dotnet to ensure we build something that developers like and are productive with.

Thanks!

Author

James Newton-King
Principal Software Engineer

I build APIs and servers for ASP.NET Core.

23 comments

Discussion is closed. Login to edit/delete existing comments.

  • Ben Hayat

    James, can you bring us up to date on the status of gRPC-Web and Blazor Client please? Perhaps a new blog as we’re getting closer to Blazor client release?

    Thanks!
    ..Ben

  • Darren Sandford

    I successfully managed to get a grpc-web service working using Kestrel, but then attempted to convert it to using Http.sys (not under IIS), but I've tried and failed to get it working, always getting a "The response headers cannot be modified because the response has already starteed." invalid operation exception.

    Am I completely barking up the wrong tree - does this experiment not support http.sys in this way?

    A little frustrated - this is exactly the use...

    Read more
  • Joacim Wall

    Hi i try to use this from Xamarin forms and it work when i publish the server to azure but i am not able to debug on local dev computer from Android.
    i have tested to follow the instruction on thttps://go.microsoft.com/fwlink/?linkid=2099682.

    so i add this on the client side.
    handlerdev = new HttpClientHandler();
    handlerdev.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
    ...

    Read more
  • Rick Way

    Is there a sample project for this? In my attempt, the server is returning 200 after a couple of seconds, but the client is reporting a 404 after a few milliseconds. I’m assuming I’ve got something setup wrong, but I’ve been scratching my head over it.

  • Will Blackburn

    We've already got some gRPC clients (Dotnet Core Worker Service) running using reverse proxies and Kestrel, but are keen to switch to App Service Plans (or even a VM and IIS) as this is the business standard approach. As such, this post was a great bit of news and so we quickly set about converting the start up in both client and server to support it.

    Having deployed to both VM running IIS and then an...

    Read more
  • Luke Kenyon

    Hi, You mention that gRPC-Web will work with IIS before I commit some time what would be the correct way of hosting the gRPC Service on IIS?

    • James Newton-KingMicrosoft employee Author

      There are no special requirements for gRPC-Web on IIS. It works with HTTP/1.1 and HTTP/2. It works with TLS and without TLS.

      • David Graham

        I have tested this in IIS, but the client just waits on SayHelloAsync. If you shutdown the server however then you get 404.

  • Anthony GIRETTI

    Hi!

    I was impatient to use gRPC in a Browser, gRPC-Web with ASP.NET Core made it real, I have been able to build an Angular 8 app with gRPC-Web.
    Thank you! I really enjoy the feature, I would love to use that in production.

    Here is the repository of the Angular 8 app: https://github.com/AnthonyGiretti/angular8-grpc-aspnetcore3-1-demo

  • David Inggs

    Thanks for the article, it was very helpful.

    I've been trying to get a Grpc Server to Stream to a Blazor WebAssembly application without luck. The examples for Blazer only show a Unary call, not a streaming example.

    My attempts at adding this show a stream coming through in the network (via Chrome dev tools) but the code isn't picking it up in the Blazor Web app. I've made sure the HttpClient is in GrpcWebText...

    Read more
    • Olivier HOUSSIN

      I have the same behavior on my program, impossible to operate the server streaming mode, I hope it will be implemented before the release of version 2.27

  • Zeeshan Hirani

    Is it possible to generate proto files from my C# contract. I am new to GRPC but not new to C#. I would like the ability define my C# contract and generate a proto file from that.

    • Shimmy Weitzhandler

      Same question here.
      WOW Zeeshan are you alive? Used to read your articles and books. Good to see you around! What’s your handle?

      I also wonder what about inheritance, validation logic or other shared entity implementations.

  • Brad Triebwasser

    Looks great! Are there any plans to support model (proto) validation? gRPC looks promising but the lack of model validation is which normal ASP/ViewModels provides is making me hesitant to make the switch.