Delen via


gRPC JSON-transcodering in ASP.NET Core

Opmerking

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 10-versie van dit artikel voor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET- en .NET Core-ondersteuningsbeleid voor meer informatie. Zie de .NET 10-versie van dit artikel voor de huidige release.

Door James Newton-King

gRPC is een RPC-framework (Remote Procedure Call) met hoge prestaties. gRPC maakt gebruik van HTTP/2, streaming, Protobuf en berichtcontracten om hoogwaardige, realtime services te maken.

Eén beperking met gRPC is dat niet elk platform het kan gebruiken. Browsers bieden geen volledige ondersteuning voor HTTP/2, waardoor REST API's en JSON de primaire manier zijn om gegevens in browser-apps op te halen. Ondanks de voordelen die gRPC biedt, REST hebben API's en JSON een belangrijke plaats in moderne apps. Het bouwen van gRPC - en JSON-web-API's voegt ongewenste overhead toe aan app-ontwikkeling.

In dit document wordt beschreven hoe u JSON-web-API's maakt met behulp van gRPC-services.

Overzicht

gRPC JSON-transcodering is een extensie voor ASP.NET Core waarmee RESTful JSON-API's voor gRPC-services worden gemaakt. Na de configuratie kunnen apps met transcodering gRPC-services aanroepen met vertrouwde HTTP-concepten:

  • HTTP-werkwoorden
  • URL-parameterbinding
  • JSON-aanvragen/antwoorden

gRPC kan nog steeds worden gebruikt om services aan te roepen.

Opmerking

gRPC JSON-transcodering vervangt gRPC HTTP API, een alternatieve experimentele extensie.

Usage

  1. Voeg een pakketreferentie toe aan Microsoft.AspNetCore.Grpc.JsonTranscoding.

  2. Registreer transcodering in de opstartcode van de server door AddJsonTranscoding toe te voegen: wijzig Program.cs naar builder.Services.AddGrpc(); in het builder.Services.AddGrpc().AddJsonTranscoding(); bestand.

  3. Toevoegen <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos> aan de eigenschapsgroep in het projectbestand (.csproj):

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <InvariantGlobalization>true</InvariantGlobalization>
        <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>
      </PropertyGroup>
    
  4. Aantekeningen toevoegen aan gRPC-methoden in uw .proto bestanden met HTTP-bindingen en routes:

    syntax = "proto3";
    
    option csharp_namespace = "GrpcServiceTranscoding";
    import "google/api/annotations.proto";
    
    package greet;
    
    // The greeting service definition.
    service Greeter {
      rpc SayHello (HelloRequest) returns (HelloReply) {
        option (google.api.http) = {
          get: "/v1/greeter/{name}"
        };
      }
    }
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings.
    message HelloReply {
      string message = 1;
    }
    

De SayHello gRPC-methode kan nu worden aangeroepen als gRPC en als een JSON-web-API:

  • Aanvraag: GET /v1/greeter/world
  • Antwoord: { "message": "Hello world" }

Als de server is geconfigureerd voor het schrijven van logboeken voor elke aanvraag, laten serverlogboeken zien dat een gRPC-service de HTTP-aanroep uitvoert. Transcodering wijst de binnenkomende HTTP-aanvraag toe aan een gRPC-bericht en converteert het antwoordbericht naar JSON.

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET https://localhost:5001/v1/greeter/world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /v1/greeter/{name}'
info: Server.GreeterService[0]
      Sending hello to world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /v1/greeter/{name}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 1.996ms 200 application/json

Aantekeningen toevoegen aan gRPC-methoden

gRPC-methoden moeten worden geannoteerd met een HTTP-regel voordat ze transcodering ondersteunen. De HTTP-regel bevat informatie over het aanroepen van de gRPC-methode, zoals de HTTP-methode en route.

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

Het voorbeeld van de procedure:

  • Hiermee definieert u een Greeter service met een SayHello methode. De methode heeft een HTTP-regel opgegeven met behulp van de naam google.api.http.
  • De methode is toegankelijk met GET aanvragen en de /v1/greeter/{name} route.
  • Het name veld in het aanvraagbericht is gebonden aan een routeparameter.

Er zijn veel opties beschikbaar om aan te passen hoe een gRPC-methode wordt verbonden met een RESTful-API. Zie HTTP en JSON configureren voor gRPC-transcodering voor meer informatie over het toevoegen van aantekeningen bij gRPC-methoden en het aanpassen van JSON.

Streamingmethoden

Traditionele gRPC via HTTP/2 ondersteunt streaming in alle richtingen. Transcodering is beperkt tot server-streaming alleen. Clientstreaming- en bidirectionele streamingmethoden worden niet ondersteund.

Serverstreamingmethoden maken gebruik van JSON met regelscheidingstekens. Elk bericht dat met WriteAsync wordt geschreven, wordt geserialiseerd naar JSON en gevolgd door een nieuwe regel.

Met de volgende streamingmethode voor de server worden drie berichten geschreven:

public override async Task StreamingFromServer(ExampleRequest request,
    IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
{
    for (var i = 1; i <= 3; i++)
    {
        await responseStream.WriteAsync(new ExampleResponse { Text = $"Message {i}" });
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}

De client ontvangt drie met regels gescheiden JSON-objecten:

{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}

Houd er rekening mee dat de WriteIndented JSON-instelling niet van toepassing is op serverstreamingmethoden. Mooie weergave voegt nieuwe regels en witruimte toe aan JSON, wat niet compatibel is met regelgescheiden JSON.

Bekijk of download een voorbeeld van een ASP.NET Core gPRC-transcoderings- en streaming-app.

HTTP-protocol

De ASP.NET Core gRPC-servicesjabloon, opgenomen in de .NET SDK, maakt een app die alleen is geconfigureerd voor HTTP/2. HTTP/2 is een goede standaardinstelling wanneer een app alleen ondersteuning biedt voor traditionele gRPC via HTTP/2. Transcodering werkt echter met zowel HTTP/1.1 als HTTP/2. Sommige platforms, zoals UWP of Unity, kunnen HTTP/2 niet gebruiken. Als u alle client-apps wilt ondersteunen, configureert u de server om HTTP/1.1 en HTTP/2 in te schakelen.

Het standaardprotocol bijwerken in appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Alternatief, configureert u Kestrel eindpunten in opstartcode.

Voor het inschakelen van HTTP/1.1 en HTTP/2 op dezelfde poort is TLS vereist voor protocolonderhandeling. Zie ASP.NET Core gRPC-protocolonderhandeling voor meer informatie over het configureren van HTTP-protocollen in een gRPC-app.

gRPC JSON-transcodering versus gRPC-Web

Met zowel transcodering als gRPC-Web kunnen gRPC-services vanuit een browser worden aangeroepen. De manier waarop elk dit doet, is echter anders:

  • met gRPC-Web kunnen browser-apps gRPC-services vanuit de browser aanroepen met de gRPC-webclient en Protobuf. gRPC-Web vereist dat de browser-app een gRPC-client genereert en het voordeel heeft van het verzenden van kleine, snelle Protobuf-berichten.
  • Met transcodering kunnen browser-apps gRPC-services aanroepen alsof ze RESTful API's met JSON waren. De browser-app hoeft geen gRPC-client te genereren of iets te weten te komen over gRPC.

De vorige Greeter service kan worden aangeroepen met behulp van JavaScript-API's van de browser:

var name = nameInput.value;

fetch('/v1/greeter/' + name)
  .then((response) => response.json())
  .then((result) => {
    console.log(result.message);
    // Hello world
  });

grpc-gateway

grpc-gateway is een andere technologie voor het maken van RESTful JSON-API's van gRPC-services. Er worden dezelfde .proto aantekeningen gebruikt om HTTP-concepten toe te wijzen aan gRPC-services.

grpc-gateway maakt gebruik van het genereren van code om een reverse-proxyserver te maken. De omgekeerde proxy vertaalt RESTful-aanroepen naar gRPC+Protobuf en verzendt de aanroepen via HTTP/2 naar de gRPC-service. Het voordeel van deze benadering is dat de gRPC-service niet weet wat de RESTful JSON-API's zijn. Elke gRPC-server kan grpc-gateway gebruiken.

Ondertussen wordt gRPC JSON-transcodering uitgevoerd in een ASP.NET Core-app. JSON wordt gedeserialiseerd in Protobuf-berichten en roept vervolgens de gRPC-service rechtstreeks aan. Transcodering in ASP.NET Core biedt voordelen voor ontwikkelaars van .NET-apps:

  • Minder complex: Zowel gRPC-services als toegewezen RESTful JSON-API lopen uit één ASP.NET Core-app.
  • Betere prestaties: Transcodering deserializeert JSON naar Protobuf-berichten en roept de gRPC-service rechtstreeks aan. Er zijn aanzienlijke prestatievoordelen bij het uitvoeren van dit proces versus het maken van een nieuwe gRPC-aanroep naar een andere server.
  • Lagere kosten: minder servers resulteren in een kleinere maandelijkse hostingfactuur.

Zie de "handleiding van de grpc-gateway" voor installatie en gebruik van grpc-gateway.

Aanvullende bronnen

gRPC is een RPC-framework (Remote Procedure Call) met hoge prestaties. gRPC maakt gebruik van HTTP/2, streaming, Protobuf en berichtcontracten om hoogwaardige, realtime services te maken.

Eén beperking met gRPC is dat niet elk platform het kan gebruiken. Browsers bieden geen volledige ondersteuning voor HTTP/2, waardoor REST API's en JSON de primaire manier zijn om gegevens in browser-apps op te halen. Ondanks de voordelen die gRPC biedt, REST hebben API's en JSON een belangrijke plaats in moderne apps. Het bouwen van gRPC - en JSON-web-API's voegt ongewenste overhead toe aan app-ontwikkeling.

In dit document wordt beschreven hoe u JSON-web-API's maakt met behulp van gRPC-services.

Overzicht

gRPC JSON-transcodering is een extensie voor ASP.NET Core waarmee RESTful JSON-API's voor gRPC-services worden gemaakt. Na de configuratie kunnen apps met transcodering gRPC-services aanroepen met vertrouwde HTTP-concepten:

  • HTTP-werkwoorden
  • URL-parameterbinding
  • JSON-aanvragen/antwoorden

gRPC kan nog steeds worden gebruikt om services aan te roepen.

Opmerking

gRPC JSON-transcodering vervangt gRPC HTTP API, een alternatieve experimentele extensie.

Usage

  1. Voeg een pakketreferentie toe aan Microsoft.AspNetCore.Grpc.JsonTranscoding.
  2. Registreer transcodering in de opstartcode van de server door AddJsonTranscoding toe te voegen: wijzig Program.cs naar builder.Services.AddGrpc(); in het builder.Services.AddGrpc().AddJsonTranscoding(); bestand.
  3. Maak de mapstructuur /google/api in de projectmap die het .csproj bestand bevat.
  4. Voeg google/api/http.proto en google/api/annotations.proto bestanden toe aan de /google/api directory.
  5. Aantekeningen toevoegen aan gRPC-methoden in uw .proto bestanden met HTTP-bindingen en routes:
syntax = "proto3";

option csharp_namespace = "GrpcServiceTranscoding";
import "google/api/annotations.proto";

package greet;

// The greeting service definition.
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

De SayHello gRPC-methode kan nu worden aangeroepen als gRPC en als een JSON-web-API:

  • Aanvraag: GET /v1/greeter/world
  • Antwoord: { "message": "Hello world" }

Als de server is geconfigureerd voor het schrijven van logboeken voor elke aanvraag, laten serverlogboeken zien dat een gRPC-service de HTTP-aanroep uitvoert. Transcodering wijst de binnenkomende HTTP-aanvraag toe aan een gRPC-bericht en converteert het antwoordbericht naar JSON.

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET https://localhost:5001/v1/greeter/world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /v1/greeter/{name}'
info: Server.GreeterService[0]
      Sending hello to world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /v1/greeter/{name}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 1.996ms 200 application/json

Aantekeningen toevoegen aan gRPC-methoden

gRPC-methoden moeten worden geannoteerd met een HTTP-regel voordat ze transcodering ondersteunen. De HTTP-regel bevat informatie over het aanroepen van de gRPC-methode, zoals de HTTP-methode en route.

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

Het voorbeeld van de procedure:

  • Hiermee definieert u een Greeter service met een SayHello methode. De methode heeft een HTTP-regel opgegeven met behulp van de naam google.api.http.
  • De methode is toegankelijk met GET aanvragen en de /v1/greeter/{name} route.
  • Het name veld in het aanvraagbericht is gebonden aan een routeparameter.

Er zijn veel opties beschikbaar om aan te passen hoe een gRPC-methode wordt verbonden met een RESTful-API. Zie HTTP en JSON configureren voor gRPC-transcodering voor meer informatie over het toevoegen van aantekeningen bij gRPC-methoden en het aanpassen van JSON.

Streamingmethoden

Traditionele gRPC via HTTP/2 ondersteunt streaming in alle richtingen. Transcodering is beperkt tot server-streaming alleen. Clientstreaming- en bidirectionele streamingmethoden worden niet ondersteund.

Serverstreamingmethoden maken gebruik van JSON met regelscheidingstekens. Elk bericht dat met WriteAsync wordt geschreven, wordt geserialiseerd naar JSON en gevolgd door een nieuwe regel.

Met de volgende streamingmethode voor de server worden drie berichten geschreven:

public override async Task StreamingFromServer(ExampleRequest request,
    IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
{
    for (var i = 1; i <= 3; i++)
    {
        await responseStream.WriteAsync(new ExampleResponse { Text = $"Message {i}" });
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}

De client ontvangt drie met regels gescheiden JSON-objecten:

{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}

Houd er rekening mee dat de WriteIndented JSON-instelling niet van toepassing is op serverstreamingmethoden. Mooie weergave voegt nieuwe regels en witruimte toe aan JSON, wat niet compatibel is met regelgescheiden JSON.

Bekijk of download een voorbeeld van een ASP.NET Core gPRC-transcoderings- en streaming-app.

HTTP-protocol

De ASP.NET Core gRPC-servicesjabloon, opgenomen in de .NET SDK, maakt een app die alleen is geconfigureerd voor HTTP/2. HTTP/2 is een goede standaardinstelling wanneer een app alleen ondersteuning biedt voor traditionele gRPC via HTTP/2. Transcodering werkt echter met zowel HTTP/1.1 als HTTP/2. Sommige platforms, zoals UWP of Unity, kunnen HTTP/2 niet gebruiken. Als u alle client-apps wilt ondersteunen, configureert u de server om HTTP/1.1 en HTTP/2 in te schakelen.

Het standaardprotocol bijwerken in appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Alternatief, configureert u Kestrel eindpunten in opstartcode.

Voor het inschakelen van HTTP/1.1 en HTTP/2 op dezelfde poort is TLS vereist voor protocolonderhandeling. Zie ASP.NET Core gRPC-protocolonderhandeling voor meer informatie over het configureren van HTTP-protocollen in een gRPC-app.

gRPC JSON-transcodering versus gRPC-Web

Met zowel transcodering als gRPC-Web kunnen gRPC-services vanuit een browser worden aangeroepen. De manier waarop elk dit doet, is echter anders:

  • met gRPC-Web kunnen browser-apps gRPC-services vanuit de browser aanroepen met de gRPC-webclient en Protobuf. gRPC-Web vereist dat de browser-app een gRPC-client genereert en het voordeel heeft van het verzenden van kleine, snelle Protobuf-berichten.
  • Met transcodering kunnen browser-apps gRPC-services aanroepen alsof ze RESTful API's met JSON waren. De browser-app hoeft geen gRPC-client te genereren of iets te weten te komen over gRPC.

De vorige Greeter service kan worden aangeroepen met behulp van JavaScript-API's van de browser:

var name = nameInput.value;

fetch('/v1/greeter/' + name)
  .then((response) => response.json())
  .then((result) => {
    console.log(result.message);
    // Hello world
  });

grpc-gateway

grpc-gateway is een andere technologie voor het maken van RESTful JSON-API's van gRPC-services. Er worden dezelfde .proto aantekeningen gebruikt om HTTP-concepten toe te wijzen aan gRPC-services.

grpc-gateway maakt gebruik van het genereren van code om een reverse-proxyserver te maken. De omgekeerde proxy vertaalt RESTful-aanroepen naar gRPC+Protobuf en verzendt de aanroepen via HTTP/2 naar de gRPC-service. Het voordeel van deze benadering is dat de gRPC-service niet weet wat de RESTful JSON-API's zijn. Elke gRPC-server kan grpc-gateway gebruiken.

Ondertussen wordt gRPC JSON-transcodering uitgevoerd in een ASP.NET Core-app. JSON wordt gedeserialiseerd in Protobuf-berichten en roept vervolgens de gRPC-service rechtstreeks aan. Transcodering in ASP.NET Core biedt voordelen voor ontwikkelaars van .NET-apps:

  • Minder complex: Zowel gRPC-services als toegewezen RESTful JSON-API lopen uit één ASP.NET Core-app.
  • Betere prestaties: Transcodering deserializeert JSON naar Protobuf-berichten en roept de gRPC-service rechtstreeks aan. Er zijn aanzienlijke prestatievoordelen bij het uitvoeren van dit proces versus het maken van een nieuwe gRPC-aanroep naar een andere server.
  • Lagere kosten: minder servers resulteren in een kleinere maandelijkse hostingfactuur.

Zie de "handleiding van de grpc-gateway" voor installatie en gebruik van grpc-gateway.

Aanvullende bronnen