Konfigurieren von Sie HTTP und JSON für Apps zur gRPC JSON-Transcodierung

Von James Newton-King

Bei der gRPC JSON-Transcodierung werden RESTful JSON-Web-APIs aus gRPC-Methoden erstellt. Dabei werden Anmerkungen und Optionen zum Anpassen der Zuordnung einer RESTful-API zu den gRPC-Methoden verwendet.

HTTP-Regeln

gRPC-Methoden müssen mit einer HTTP-Regel versehen werden, damit sie die Transcodierung unterstützen. Die HTTP-Regel enthält Informationen zum Aufrufen der gRPC-Methode als RESTful-API, z. B. als HTTP-Methode und Route.

import "google/api/annotations.proto";

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

Eine HTTP-Regel ist:

Hinweis

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

HTTP-Methode

Die HTTP-Methode wird angegeben, indem Sie die Route auf den übereinstimmenden HTTP-Methodenfeldnamen festlegen:

  • get
  • put
  • post
  • delete
  • patch

Das Feld custom ermöglicht andere HTTP-Methoden.

Im folgenden Beispiel wird die CreateAddress-Methode POST mit der angegebenen Route zugeordnet:

service Address {
  rpc CreateAddress (CreateAddressRequest) returns (CreateAddressReply) {
    option (google.api.http) = {
      post: "/v1/address",
      body: "*"
    };
  }
}

Route

gRPC JSON-Transcodierungsrouten unterstützen Routenparameter. So wird z. B. {name} in einer Route an das Feld name in der Anforderungsnachricht gebunden.

Um ein Feld an eine geschachtelte Nachricht zu binden, geben Sie den Pfad zu dem Feld an. Im folgenden Beispiel wird {params.org} an das Feld org in der IssueParams-Nachricht gebunden:

service Repository {
  rpc GetIssue (GetIssueRequest) returns (GetIssueReply) {
    option (google.api.http) = {
      get: "/{apiVersion}/{params.org}/{params.repo}/issue/{params.issueId}"
    };
  }
}

message GetIssueRequest {
  int32 api_version = 1;
  IssueParams params = 2;
}
message IssueParams {
  string org = 1;
  string repo = 2;
  int32 issueId = 3;
}

Transcodierungsrouten und ASP.NET Core-Routen weisen eine ähnliche Syntax und einen ähnlichen Merkmalssatz auf. Einige ASP.NET Core-Routingfeatures werden jedoch von der Transcodierung nicht unterstützt. Dazu gehören:

Anforderungstext

Während der Transcodierung wird der JSON-Code im Anforderungstext in die Anforderungsnachricht deserialisiert. Das Feld body gibt an, wie der HTTP-Anforderungstext der Anforderungsnachricht zugeordnet wird. Der Wert ist entweder der Name des Anforderungsfelds, dessen Wert dem HTTP-Anforderungstext zugeordnet ist, oder *, um alle Anforderungsfelder zuzuordnen.

Im folgenden Beispiel wird der HTTP-Anforderungstext in das Feld address deserialisiert:

service Address {
  rpc AddAddress (AddAddressRequest) returns (AddAddressReply) {
    option (google.api.http) = {
      post: "/{apiVersion}/address",
      body: "address"
    };
  }
}

message AddAddressRequest {
  int32 api_version = 1;
  Address address = 2;
}
message Address {
  string street = 1;
  string city = 2;
  string country = 3;
}

Abfrageparameter

Alle Felder in der Anforderungsnachricht, die nicht an Routenparameter gebunden sind, oder der Anforderungstext können mithilfe von HTTP-Abfrageparametern festgelegt werden.

service Repository {
  rpc GetIssues (GetIssuesRequest) returns (GetIssuesReply) {
    option (google.api.http) = {
      get: "/v1/{org}/{repo}/issue"
    };
  }
}

message GetIssuesRequest {
  string org = 1;
  string repo = 2;
  string text = 3;
  PageParams page = 4;
}
message PageParams {
  int32 index = 1;
  int32 size = 2;
}

Im vorherigen Beispiel:

  • Die Felder org und repo wurden über Routenparametern gebunden.
  • Andere Felder, z. B. text und die geschachtelten Felder aus page, können über die Abfragezeichenfolge gebunden werden: ?text=value&page.index=0&page.size=10

Antworttext

Standardmäßig wird bei der Transcodierung die gesamte Antwortnachricht als JSON serialisiert. Das Feld response_body ermöglicht die Einschränkung der Serialisierung auf einen Teil der Antwortnachricht.

service Address {
  rpc GetAddress (GetAddressRequest) returns (GetAddressReply) {
    option (google.api.http) = {
      get: "/v1/address/{id}",
      response_body: "address"
    };
  }
}

message GetAddressReply {
  int32 version = 1;
  Address address = 2;
}
message Address {
  string street = 1;
  string city = 2;
  string country = 3;
}

Im vorherigen Beispiel wird das Feld address im Antworttext als JSON serialisiert.

Spezifikation

Weitere Informationen zum Anpassen der gRPC-Transcodierung finden Sie in der HttpRule-Spezifikation.

Anpassen von JSON-Code

Nachrichten werden mithilfe der JSON-Zuordnung in der Protobuf-Spezifikation in und von JSON konvertiert. Die JSON-Zuordnung von Protobuf stellt eine standardisierte Methode zum Konvertieren zwischen JSON und Protobuf dar, und alle Serialisierungen folgen diesen Regeln.

Die gRPC JSON-Transcodierung bietet jedoch einige eingeschränkte Optionen zum Anpassen des JSON-Codes mit GrpcJsonSettings, wie in der folgenden Tabelle dargestellt.

Option Standardwert BESCHREIBUNG
IgnoreDefaultValues false Bei Festlegung auf true werden Felder mit Standardwerten während der Serialisierung ignoriert.
WriteEnumsAsIntegers false Bei Festlegung auf true werden Enumerationswerte als Integer und nicht als Zeichenfolgen geschrieben.
WriteInt64sAsStrings false Bei Festlegung auf true werden Int64- und UInt64-Werte als Zeichenfolgen und nicht als Zahlen geschrieben.
WriteIndented false Bei Festlegung auf true wird JSON-Code mit automatischer Strukturierung und Einrückung geschrieben. Diese Option wirkt sich nicht auf Streamingmethoden aus, die zeilenbegrenzte JSON-Nachrichten schreiben und daher die automatische Strukturierung und Einrückung nicht nutzen können.
builder.Services.AddGrpc().AddJsonTranscoding(o =>
{
    o.JsonSettings.WriteIndented = true;
});

In der Datei .proto passt die Feldoption json_name den Namen eines Felds an, wenn es wie im folgenden Beispiel als JSON-Code serialisiert wird:

message TestMessage {
  string my_field = 1 [json_name="customFieldName"];
}

Bei der Transcodierung werden keine erweiterten JSON-Anpassungen unterstützt. Für Apps, die eine genaue Steuerung der JSON-Struktur erfordern, sollten Sie die Verwendung der ASP.NET Core-Web-API in Betracht ziehen.

Zusätzliche Ressourcen