Configurer un service gRPC

Pour créer un service gRPC, que vous utilisiez ou non API Gateway, vous devez indiquer la définition de l'interface dans un ou plusieurs fichiers proto, qui sont des fichiers texte portant l'extension .proto. Dans un fichier proto, vous définissez la surface de votre API, y compris les structures de données, les méthodes, les paramètres de méthode et les types de renvois. Vous compilez ensuite votre fichier proto à l'aide du tampon de protocole spécifique au langage, protoc. Pour plus d'informations, consultez les sections Qu'est-ce que gRPC ? et Concepts de gRPC.

Pour que votre service gRPC soit géré par API Gateway, outre le fichier proto compilé, vous devez spécifier une configuration de service dans un ou plusieurs fichiers YAML. Une configuration de service est une spécification qui vous permet de définir le comportement d'un service gRPC, y compris l'authentification, les quotas, etc.

Présentation de la configuration de service

En haut du fichier YAML, vous pouvez spécifier des informations de base sur le service, telles que son nom et son titre. D'autres aspects du service sont configurés dans les sous-sections du fichier YAML, par exemple:

Exemple :

type: google.api.Service
config_version: 3
name: calendar.googleapis.com
title: Google Calendar API
apis:
- name: google.calendar.v3.Calendar
authentication:
  providers:
  - id: google_calendar_auth
    jwks_uri: https://www.googleapis.com/oauth2/v1/certs
    issuer: https://securetoken.google.com
  rules:
  - selector: "*"
    requirements:
      provider_id: google_calendar_auth
backend:
  rules:
    - selector: "*"
      address: grpcs://my-service-98sdf8sd0-uc.a.run.app

Chaque sous-section correspond généralement à un message .proto dans lequel vous configurez divers aspects du service. Exemple :

  • authentication : spécifie la manière dont les appelants sont authentifiés.
  • backend : contrôle le routage du backend distant.
  • http : définit les règles pour mapper une méthode RPC sur une ou plusieurs méthodes API HTTP REST.
  • usage : permet d'activer et de désactiver de manière sélective la validation des clés API.

Le schéma officiel de la configuration de service est défini par le message .proto google.api.Service.

Configuration de base

L'exemple Bookstore, utilisé dans le tutoriel Premiers pas avec API Gateway et Cloud Run pour gRPC, comprend un fichier de définition d'interface de base et un fichier de configuration de service.

Définition de l'interface Bookstore, bookstore.proto :

syntax = "proto3";

package endpoints.examples.bookstore;

option java_multiple_files = true;
option java_outer_classname = "BookstoreProto";
option java_package = "com.google.endpoints.examples.bookstore";

import "google/protobuf/empty.proto";

service Bookstore {
  rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) {}
  rpc CreateShelf(CreateShelfRequest) returns (Shelf) {}
  rpc GetShelf(GetShelfRequest) returns (Shelf) {}
  rpc DeleteShelf(DeleteShelfRequest) returns (google.protobuf.Empty) {}
  rpc ListBooks(ListBooksRequest) returns (ListBooksResponse) {}
  rpc CreateBook(CreateBookRequest) returns (Book) {}
  rpc GetBook(GetBookRequest) returns (Book) {}
  rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {}
}

message Shelf {
  int64 id = 1;
  string theme = 2;
}

message Book {
  int64 id = 1;
  string author = 2;
  string title = 3;
}

Configuration de service Bookstore, api_config.yaml :

type: google.api.Service
config_version: 3

name: *.apigateway.PROJECT_ID.cloud.goog

title: Bookstore gRPC API
apis:
- name: endpoints.examples.bookstore.Bookstore

L'exemple de code précédent est la configuration de service la plus simple :

  • Il définit un service nommé *.apigateway.PROJECT_ID.cloud.goog, où PROJECT_ID correspond au nom de votre ID de projet Google Cloud.
  • Elle indique que le service expose l'API endpoints.examples.bookstore.Bookstore, comme défini dans le fichier bookstore.proto.

Règles et sélecteurs

Dans certains cas, vous aurez peut-être besoin d'associer une configuration aux éléments individuels d'un service, par exemple, pour appliquer l'authentification à certaines méthodes mais pas à d'autres. Pour que vous puissiez configurer cela dans votre configuration de service, certaines parties de la configuration de service, telles que authentication et http, permettent de spécifier des règles et des sélecteurs. Un sélecteur identifie les éléments du service (par exemple, le nom de la méthode) auxquels la configuration associée à la règle s'applique.

Un sélecteur est une liste d'éléments séparés par une virgule de noms qualifiés dans le service : méthode, message, champ, énumération ou valeurs d'énumération. Le dernier segment du nom peut être le caractère générique *, qui correspond à n'importe quel suffixe. Les caractères génériques sont autorisés uniquement à la fin d'un nom et uniquement pour un segment entier du nom. Par exemple, foo.* est accepté, mais foo.b* ou foo.*.bar ne le sont pas. Pour configurer une valeur par défaut pour tous les éléments applicables, vous devez spécifier * par lui-même.

Exemple 1 (concernant l'ensemble du service) :

usage:
  rules:
  # Allow unregistered calls for all methods.
  - selector: "*"
    allow_unregistered_calls: true

Exemple 2 (concernant une seule méthode) :

usage:
  rules: # IMPORTANT: ONLY LAST MATCHING RULE IS APPLIED
  # Disable API key validation on just the ListShelves method
  # while requiring an API key for the rest of the API.
  - selector: "*"
    allow_unregistered_calls: false
  - selector: "endpoints.examples.bookstore.BookStore.ListShelves"
    allow_unregistered_calls: true

L'exemple précédent montre comment exiger la validation de la clé API pour toutes les méthodes, à l'exception la méthode ListShelves.

Les règles sont évaluées séquentiellement, la dernière à correspondre dans l'ordre de déclaration est appliqué.

Utiliser plusieurs fichiers YAML

Vous trouverez peut-être utile d'utiliser plusieurs fichiers YAML pour configurer différentes fonctionnalités pour le même service. Le fait d'utiliser plusieurs fichiers YAML facilite leur réutilisation et leur modification pour différents environnements. Par exemple, dans l'exemple Bookstore, la configuration de base est spécifiée dans le fichier api_config.yaml, et ses règles HTTP dans le fichier api_config_http.yaml. Cela vous permet de déployer les règles HTTP uniquement si vous souhaitez activer le transcodage JSON/HTTP vers gRPC pour le Bookstore.

Si vous utilisez plusieurs fichiers YAML pour votre configuration de service, le traitement effectué lors du déploiement de la configuration est le suivant : les fichiers sont convertis en messages proto google.api.Service, puis tous les messages sont fusionnés à l'aide de la sémantique de fusion proto. En d'autres termes, tous les champs scalaires singuliers de la dernière instance remplacent ceux de la première. Ainsi, si vous fournissez différentes valeurs singulières pour la même règle dans deux fichiers, la valeur du deuxième fichier que vous spécifiez lors du déploiement de la configuration est utilisée. Les messages intégrés singuliers sont fusionnés et les champs répétés sont concaténés.

Comme les règles, la fusion est sensible à l'ordre. S'il existe deux configurations de service, la deuxième configuration de service a la priorité sur la première.

Annotations (règles HTTP uniquement)

Au lieu d'utiliser un fichier YAML pour configurer les options HTTP, vous pouvez les configurer directement dans votre fichier proto en utilisant le mécanisme des options. Les annotations d'API sont définies dans le fichier annotations.proto.

Utilisez des annotations si l'option de configuration est destinée à être invariante dans toutes les utilisations de la définition d'interface de tampon de protocole. Par exemple, si une API possède une seule mise en œuvre ou si toutes les mises en œuvre doivent avoir la même interface HTTP, la configuration HTTP peut être annotée dans le fichier proto.

Si une option de configuration est fournie à la fois dans le fichier proto et dans le fichier YAML de configuration de service, la configuration de service remplace l'annotation.

Exemple d'annotation dans un fichier proto :

rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) {
    option (google.api.http) = { get: "/v1/shelves" };
}

# The preceding annotation is equivalent to the following service configuration:

http:
  rules:
  - selector: endpoints.examples.bookstore.BookStore.ListShelves
    get: '/v1/shelves'

Pour plus d'informations, consultez la section Transcoder HTTP/JSON vers gRPC.

Étapes suivantes