<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>pawelkmiec.net</title>
		<description>Paweł Kmieć personal blog</description>
		<link>/</link>
		<atom:link href="/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>gRPC performance benchmark in ASP.NET Core 3</title>
				<description>&lt;p&gt;In &lt;a href=&quot;https://pawelkmiec.net/2019/10/18/gRPC-ASP.NET-Core.html&quot;&gt;the previous post&lt;/a&gt;, I have explored the new gRPC service template from Visual Studio.&lt;/p&gt;

&lt;p&gt;However, I haven’t done any check of the performance of the gRPC, which I think is an interesting thing to look at. The performance benefit is a “selling point” of gRPC, so it will be good to verify how big the gain is.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;I’ll start with the results as they are probably the most interesting thing.&lt;/p&gt;

&lt;p&gt;For a quick overview, see the charts below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/gRPC-performance/small-int.png&quot; alt=&quot;Performance results for small message with integers&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/gRPC-performance/small-mixed.png&quot; alt=&quot;Performance results for small message with mixed data types&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/gRPC-performance/big-message.png&quot; alt=&quot;Performance results for big message&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For details, &lt;a data-toggle=&quot;collapse&quot; href=&quot;#rawData&quot;&gt;click here to view raw data&lt;/a&gt;&lt;/p&gt;

&lt;div id=&quot;rawData&quot; class=&quot;container collapse&quot;&gt;
    &lt;div class=&quot;row&quot;&gt;
        &lt;div class=&quot;col-md-4&quot;&gt;
            &lt;div&gt;
              &lt;table class=&quot;table table-condensed&quot;&gt;
                  &lt;thead&gt;
                    &lt;tr&gt;
                      &lt;th&gt;API Type&lt;/th&gt;
                      &lt;th&gt;Message&lt;/th&gt;
                      &lt;th&gt;Time [ms]&lt;/th&gt;
                    &lt;/tr&gt;
                  &lt;/thead&gt;
                  &lt;tbody&gt;
                   &lt;tr&gt;
                    &lt;td&gt;gRPC&lt;/td&gt;
                    &lt;td&gt;small-ints&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;2505&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;gRPC-CodeFirst&lt;/td&gt;
                    &lt;td&gt;small-ints&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;3080&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;System.Text.Json&lt;/td&gt;
                    &lt;td&gt;small-ints&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;3589&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;Newtonsoft.Json&lt;/td&gt;
                    &lt;td&gt;small-ints&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;3488&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;gRPC&lt;/td&gt;
                    &lt;td&gt;small-mixed&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;1982&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;gRPC-CodeFirst&lt;/td&gt;
                    &lt;td&gt;small-mixed&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;2770&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;System.Text.Json&lt;/td&gt;
                    &lt;td&gt;small-mixed&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;3825&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;Newtonsoft.Json&lt;/td&gt;
                    &lt;td&gt;small-mixed&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;3625&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;gRPC&lt;/td&gt;
                    &lt;td&gt;big-list&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;2813&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;gRPC-CodeFirst&lt;/td&gt;
                    &lt;td&gt;big-list&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;4678&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;System.Text.Json&lt;/td&gt;
                    &lt;td&gt;big-list&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;5338&lt;/td&gt;
                   &lt;/tr&gt;
                   &lt;tr&gt;
                    &lt;td&gt;Newtonsoft.Json&lt;/td&gt;
                    &lt;td&gt;big-list&lt;/td&gt;
                    &lt;td align=&quot;right&quot;&gt;38329&lt;/td&gt;
                   &lt;/tr&gt;
                  &lt;/tbody&gt;
                  &lt;/table&gt;
            &lt;/div&gt;
        &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&quot;api-types&quot;&gt;API types&lt;/h3&gt;

&lt;p&gt;As you see I’ve decided to compare 4 variants:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;gRPC&lt;/strong&gt; - official suite of &lt;a href=&quot;https://github.com/grpc/grpc-dotnet&quot;&gt;gRPC libraries&lt;/a&gt; that are associated with new Visual Studio template&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;gRPC-CodeFirst&lt;/strong&gt; - &lt;a href=&quot;https://github.com/protobuf-net/protobuf-net.Grpc&quot;&gt;protobuf-net.Grpc&lt;/a&gt;
 library, which works also for .NET Framework&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;System.Text.Json&lt;/strong&gt; - the new JSON serialization API from .NET Core 3&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Newtonsoft.Json&lt;/strong&gt; - probably doesn’t need introduction :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why these 4?&lt;/p&gt;

&lt;p&gt;Firstly, I wanted to see how gRPC performs against API based on JSON. RPC over HTTP with JSON serialization is the most prevalent thing these days.&lt;/p&gt;

&lt;p&gt;Secondly, I also wanted to look at different implementations of both gRPC &amp;amp; JSON serialization, mostly out of curiosity.&lt;/p&gt;

&lt;h3 id=&quot;test-messages&quot;&gt;Test messages&lt;/h3&gt;

&lt;p&gt;Test messages differ by size and data types used within them:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;small ints&lt;/strong&gt; - a class with a few int properties&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;small-mixed&lt;/strong&gt; - a class with a few int/string properties and a nested class&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;big-list&lt;/strong&gt; - a big list of items (1000 elements, 190kB JSON file)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;test-procedure&quot;&gt;Test procedure&lt;/h3&gt;

&lt;p&gt;In the test, I’ve done the following:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;run the API methods sequentially 1000 times on localhost, on my machine&lt;/li&gt;
  &lt;li&gt;all APIs were using HTTPS&lt;/li&gt;
  &lt;li&gt;all APIs were running on ASP.NET Core 3&lt;/li&gt;
  &lt;li&gt;all gRPC calls were unary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s not rigid science, but gives something roughly comparable.&lt;/p&gt;

&lt;p&gt;The charts report total runtime of all calls.&lt;/p&gt;

&lt;p&gt;You can review benchmark code on my &lt;a href=&quot;https://github.com/pawelkmiec/RPC.Benchmark&quot;&gt;GitHub repo&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;gRPC beats JSON by quite a big margin - from 30% to 50%.&lt;/p&gt;

&lt;p&gt;2 different gRPC flavours perform pretty close to each other. Official gRPC libraries seems to be faster.&lt;/p&gt;

&lt;p&gt;Newtonsoft.Json seems to be having problems with the serialization of big messages, which are not present in any other tested API. Or perhaps it’s System.Text.Json that’s optimised close to the metal with all new memory-efficient framework constructs.&lt;/p&gt;

&lt;p&gt;So, if you send large JSONs, then migrate to System.Text.Json to get something like a 6x speedup of serialization.&lt;/p&gt;

&lt;p&gt;If you fight for milliseconds in your APIs, then switch from JSON to gRPC is worth consideration.&lt;/p&gt;
</description>
				<pubDate>Sun, 17 Nov 2019 00:00:00 +0000</pubDate>
				<link>/2019/11/17/gRPC-performance-benchmark.html</link>
				<guid isPermaLink="true">/2019/11/17/gRPC-performance-benchmark.html</guid>
			</item>
		
			<item>
				<title>Trying out gRPC in ASP.NET Core 3</title>
				<description>&lt;p&gt;&lt;strong&gt;gRPC&lt;/strong&gt; has received first class support in ASP.NET Core 3 from Microsoft. It’s a binary RPC protocol based on Protocol Buffers created by Google that works on top of HTTP/2. It offers good performance and integration with many programming languages. Let’s try out together this new feature by looking at code generated by Visual Studio gRPC project template.&lt;/p&gt;

&lt;p&gt;You can find code described in this post on my &lt;a href=&quot;https://github.com/pawelkmiec/TryingOut.gRPC&quot; target=&quot;_blank&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;basic-project-structure&quot;&gt;Basic project structure&lt;/h2&gt;

&lt;p&gt;After we create project from the gRPC service template, we have following files structure:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;│   appsettings.Development.json
│   appsettings.json
│   Program.cs
│   Startup.cs
│   TryingOut.gRPC.Service.csproj
│
├───Properties
│       launchSettings.json
│
├───Protos
│       greet.proto
│
└───Services
        GreeterService.cs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;proto-file&quot;&gt;Proto file&lt;/h2&gt;

&lt;p&gt;gRPC is based on proto files, so let’s start by looking at greet.proto:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;First thing is syntax version declaration - proto3 is the latest one&lt;/li&gt;
  &lt;li&gt;csharp_namespace option says that all generated classes will be placed in &lt;code class=&quot;highlighter-rouge&quot;&gt;TryingOut.gRPC.Service&lt;/code&gt; namespace&lt;/li&gt;
  &lt;li&gt;package specifier is equivalent of C# namespace concept in protocol buffers&lt;/li&gt;
  &lt;li&gt;The rest of file defines single method of a service, its input and output types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s worth noting that fields in messages have to be ordered explicitly. The order should not be changed after publishing the service otherwise we ask for backward compatibility issues.&lt;/p&gt;

&lt;p&gt;All in all, I’d say that file looks nice and clean, there’s little boilerplate and RPC contract is outlined in a concise way.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;syntax&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;proto3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csharp_namespace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;TryingOut.gRPC.Service&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;definition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rpc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SayHello&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HelloRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HelloReply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;containing&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'s name
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;a-glance-at-csproj-file&quot;&gt;A glance at .csproj file&lt;/h2&gt;

&lt;p&gt;Let’s go to the .csproj file. Here we have Protobuf item with &lt;code class=&quot;highlighter-rouge&quot;&gt;GrpcServices=&quot;Server&quot;&lt;/code&gt; property which instructs msbuild task to generate server-side code of gRPC service.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;Protobuf Include=&quot;Protos\greet.proto&quot; GrpcServices=&quot;Server&quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;generated-code&quot;&gt;Generated code&lt;/h2&gt;

&lt;p&gt;After build we can peek at the generated code, which is in obj directory.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;obj\Debug\netcoreapp3.0\Greet.cs
obj\Debug\netcoreapp3.0\GreetGrpc.cs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;service-class&quot;&gt;Service class&lt;/h2&gt;

&lt;p&gt;We consume generated code by inheriting from base service class. We just have to put our logic into overrides.&lt;/p&gt;

&lt;p&gt;The base class doesn’t offer much methods or properties to use. Whole info about context of the request is passed through &lt;code class=&quot;highlighter-rouge&quot;&gt;ServerCallContext&lt;/code&gt; parameter.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    public class GreeterService : Greeter.GreeterBase
    {
        // ...

        public override Task&amp;lt;HelloReply&amp;gt; SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = &quot;Hello &quot; + request.Name
            });
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;configuration-in-startup&quot;&gt;Configuration in Startup&lt;/h2&gt;

&lt;p&gt;To make this work we have to configure gRPC in Startup class by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;AddGrpc&lt;/code&gt; and mapping all gRPC services. We have to do that by using Endpoint Routing, which got a lot of attention in the release of ASP.NET Core 3. One of the goals of Endpoint Routing is to allow seamless integration of multiple endpoint handlers in single application - we can freely mix MVC controllers and gRPC services in same project.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();
        }
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // ...

            app.UseRouting();

            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapGrpcService&amp;lt;GreeterService&amp;gt;();

                // ...
            });
        }
        
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;creating-a-client&quot;&gt;Creating a client&lt;/h2&gt;

&lt;p&gt;Let’s make a little console app that will consume the service.&lt;/p&gt;

&lt;p&gt;The first step to accomplish that is adding necessary nuget packages:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Grpc.Tools - MSBuild tasks which generate client code&lt;/li&gt;
  &lt;li&gt;Google.Protobuf - protocol buffers implementation&lt;/li&gt;
  &lt;li&gt;Grpc.Net.Client - gRPC client&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include=&quot;Google.Protobuf&quot; Version=&quot;3.10.0&quot; /&amp;gt;
    &amp;lt;PackageReference Include=&quot;Grpc.Net.Client&quot; Version=&quot;2.23.2&quot; /&amp;gt;
    &amp;lt;PackageReference Include=&quot;Grpc.Tools&quot; Version=&quot;2.24.0&quot;&amp;gt;
      &amp;lt;PrivateAssets&amp;gt;all&amp;lt;/PrivateAssets&amp;gt;
      &amp;lt;IncludeAssets&amp;gt;runtime; build; native; contentfiles; analyzers; buildtransitive&amp;lt;/IncludeAssets&amp;gt;
    &amp;lt;/PackageReference&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The next thing which we have to do is linking .proto file from server and defining &lt;code class=&quot;highlighter-rouge&quot;&gt;GrpcServices=Client&lt;/code&gt; property to configure client code generation. I guess the better way to handle that in the long run would be defining proto files in some shared project or directory, so that we emphasize through project structure that those files are something meant to be reused.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;Protobuf Include=&quot;..\TryingOut.gRPC.Service\Protos\greet.proto&quot; Link=&quot;greet.proto&quot; GrpcServices=&quot;Client&quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After those preliminary steps we can use generated code to communicate with the server.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    static async Task Main()
    {
        var channel = Grpc.Net.Client.GrpcChannel.ForAddress(&quot;https://localhost:5001&quot;);
        var client = new Greeter.GreeterClient(channel);
        var response = await client.SayHelloAsync(new HelloRequest
        {
            Name = &quot;Paweł&quot;
        });
        Console.WriteLine($&quot;Response from server: {response.Message}&quot;);
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;grpc-doesnt-work-with-iis-yet&quot;&gt;gRPC doesn’t work with IIS (yet)&lt;/h2&gt;

&lt;p&gt;As of today, IIS doesn’t support gRPC due to the issue with HTTP/2 trailing headers implementation in the http.sys Windows driver. The problem affects also Azure App Service as it uses IIS under the hood.&lt;/p&gt;

&lt;p&gt;As David Fowler says it’s not going to be a quick fix, because it involves Windows update process. See &lt;a href=&quot;https://github.com/aspnet/AspNetCore/issues/9020&quot;&gt;the issue&lt;/a&gt; on GitHub AspNetCore repository for all details.&lt;/p&gt;

&lt;p&gt;I’d say it’s one more instance of the problems stemming from Microsoft move away from single integrated ecosystem approach. It seems like the question “Will this work on IIS / Windows / Azure?” is becoming more and more relevant with the new features of the ASP.NET Core.&lt;/p&gt;

&lt;h2 id=&quot;grpc-for-net-framework&quot;&gt;gRPC for .NET Framework&lt;/h2&gt;

&lt;p&gt;If you would like to use gRPC on .NET Framework 4.X, then you should take a look at &lt;a href=&quot;https://github.com/protobuf-net/protobuf-net.Grpc&quot;&gt;protobuf-net.Grpc&lt;/a&gt;, which allows to do that. It also uses code-first approach, no need to write .proto files!&lt;/p&gt;

&lt;h2 id=&quot;closing-thoughts&quot;&gt;Closing thoughts&lt;/h2&gt;

&lt;p&gt;In a layered view of an application gRPC services sits in a similar place as controllers in the Api projects. However, HTTP is used purely as a transport protocol and nothing like RESTful principles applies here. This simplification takes away some design options, but I’d say it makes sense for RPC approach and can make development faster. We don’t even have to think of resource names for our API methods or their HTTP verbs. We just need to define proto files and consume generated code.&lt;/p&gt;

&lt;p&gt;By choosing gRPC we sacrifice interoperability and plain-text advantages for sake of performance. However, good tooling which comes with gRPC reduces a lot of the usual friction related to working with binary protocols. I guess gRPC will find its place in .NET space mostly in internal APIs which require minimal serialization overhead.&lt;/p&gt;
</description>
				<pubDate>Fri, 18 Oct 2019 00:00:00 +0000</pubDate>
				<link>/2019/10/18/gRPC-ASP.NET-Core.html</link>
				<guid isPermaLink="true">/2019/10/18/gRPC-ASP.NET-Core.html</guid>
			</item>
		
	</channel>
</rss>
