Partager via


Configurer HTTP et JSON pour le transcodage JSON gRPC

Par James Newton-King

Le transcodage JSON gRPC crée des API web RESTful JSON à partir de méthodes gRPC. Il utilise des annotations et des options pour personnaliser la façon dont une API RESTful est mappée aux méthodes gRPC.

Règles HTTP

Les méthodes gRPC doivent être annotées avec une règle HTTP avant de prendre en charge le transcodage. La règle HTTP inclut des informations sur l’appel de la méthode gRPC en tant qu’API RESTful, comme la méthode HTTP et l’itinéraire.

import "google/api/annotations.proto";

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

Une règle HTTP est :

Notes

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

HTTP method

La méthode HTTP est spécifiée en définissant l’itinéraire vers le nom du champ de la méthode HTTP correspondant :

  • get
  • put
  • post
  • delete
  • patch

Le champ custom autorise d’autres méthodes HTTP.

Dans l’exemple suivant, la méthode CreateAddress est mappée à POST avec l’itinéraire spécifié :

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

Route

Les itinéraires de transcodage gRPC JSON prennent en charge les paramètres d’itinéraire. Par exemple, {name} dans un itinéraire se lie au champ name sur le message de la requête.

Pour lier un champ à un message imbriqué, spécifiez le chemin d’accès au champ. Dans l’exemple suivant, {params.org} se lie au champ org sur le message IssueParams :

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;
}

Les itinéraires de transcodage et les itinéraires ASP.NET Core ont une syntaxe et un ensemble de fonctionnalités similaires. Toutefois, certaines fonctionnalités de routage ASP.NET Core ne sont pas prises en charge par le transcodage. Il s’agit notamment des paramètres suivants :

Corps de la demande

Le transcodage désérialise le corps de la requête JSON dans le message de la demande. Le champ body spécifie la façon dont le corps de la requête HTTP est mappé au message de la demande. La valeur est soit le nom du champ de requête dont la valeur est mappée au corps de la requête HTTP, soit * pour le mappage de tous les champs de requête.

Dans l’exemple suivant, le corps de la requête HTTP est désérialisé dans le champ address :

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;
}

Paramètres de requête

Tous les champs du message de la demande qui ne sont pas limités par les paramètres de l’itinéraire ou le corps de la demande peuvent être définis à l’aide de paramètres de requête HTTP.

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;
}

Dans l’exemple précédent :

  • Les champs org et repo sont liés à partir des paramètres de l’itinéraire.
  • D’autres champs, tels que text et les champs imbriqués de page, peuvent être limités à partir de la chaîne de requête : ?text=value&page.index=0&page.size=10

Response body

Par défaut, le transcodage sérialise l’intégralité du message de la réponse en tant que JSON. Le champ response_body permet la sérialisation d’un sous-ensemble du message de réponse.

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;
}

Dans l’exemple précédent, le champ address est sérialisé dans le corps de la réponse en tant que JSON.

Caractéristique

Pour plus d’informations sur la personnalisation du transcodage gRPC, consultez la spécification HttpRule.

Personnaliser JSON

Les messages sont convertis vers et depuis JSON à l’aide du mappage JSON dans la spécification Protobuf. Le mappage JSON de Protobuf est une méthode standardisée de conversion entre JSON et Protobuf, et toute sérialisation suit ces règles.

Toutefois, le transcodage gRPC JSON offre des options limitées pour personnaliser JSON avec GrpcJsonSettings, comme indiqué dans le tableau suivant.

Option Valeur par défaut Description
IgnoreDefaultValues false Si la valeur est définie sur true, les champs avec des valeurs par défaut sont ignorés pendant la sérialisation.
WriteEnumsAsIntegers false Si la valeur est définie sur true, les valeurs enum sont écrites sous forme d’entiers au lieu de chaînes.
WriteInt64sAsStrings false Si la valeur est définie sur true, les valeurs Int64 et UInt64 sont écrites sous forme de chaînes au lieu de nombres.
WriteIndented false Si la valeur est définie sur true, JSON est écrit à l’aide d’une impression en mode Pretty. Cette option n’affecte pas les méthodes de diffusion en continu, qui écrivent des messages JSON délimités par une ligne et ne peuvent pas utiliser l’impression en mode Pretty.
builder.Services.AddGrpc().AddJsonTranscoding(o =>
{
    o.JsonSettings.WriteIndented = true;
});

Dans le fichier .proto, l’option de champ json_name personnalise le nom d’un champ lorsqu’il est sérialisé en tant que JSON, comme dans l’exemple suivant :

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

Le transcodage ne prend pas en charge la personnalisation JSON avancée. Les applications nécessitant un contrôle précis de la structure JSON doivent envisager d’utiliser l’API web ASP.NET Core.

Ressources supplémentaires