Configurar un servicio gRPC

Para crear un servicio gRPC, tanto si usas API Gateway como si no, debes especificar la definición de interfaz en uno o varios archivos proto, que son archivos de texto con la extensión .proto. En un archivo proto, se define la superficie de la API, incluidas las estructuras de datos, los métodos, los parámetros de los métodos y los tipos de valor devuelto. A continuación, compila el archivo proto con el compilador de búfer de protocolo específico del idioma, protoc. Para obtener más información, consulta ¿Qué es gRPC? y Conceptos de gRPC.

Para que API Gateway gestione tu servicio gRPC, además del archivo proto compilado, debes especificar una configuración de servicio en uno o varios archivos YAML. Una configuración de servicio es una especificación que te permite definir el comportamiento de un servicio gRPC, como la autenticación, las cuotas y más.

Información general sobre la configuración del servicio

En la parte superior del archivo YAML, puedes especificar información básica sobre el servicio, como su nombre y título. Otros aspectos del servicio se configuran en subsecciones del archivo YAML, como las siguientes:

Por ejemplo:

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

Cada subsección suele corresponderse con un mensaje .proto en el que se configuran varios aspectos del servicio. Por ejemplo:

  • authentication: especifica cómo se autentican las personas que llaman.
  • backend: controla el enrutamiento del backend remoto.
  • http: define las reglas para asignar un método RPC a uno o varios métodos de la API REST HTTP.
  • usage: te permite habilitar e inhabilitar la validación de claves de API de forma selectiva.

El esquema oficial de la configuración del servicio se define mediante el .proto mensaje google.api.Service.

Configuración básica

El ejemplo de librería, que se usa en el tutorial Empezar a usar API Gateway y Cloud Run para gRPC, incluye un archivo de definición de interfaz básico y un archivo de configuración de servicio.

Definición de la interfaz de 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;
}

Configuración del servicio 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

El ejemplo de código anterior es la configuración de servicio más sencilla, ya que:

  • Define un servicio llamado *.apigateway.PROJECT_ID.cloud.goog donde PROJECT_ID es el nombre de tu Google Cloud ID de proyecto.
  • Especifica que el servicio expone la API endpoints.examples.bookstore.Bookstore, tal como se define en el archivo bookstore.proto.

Reglas y selectores

En algunos casos, es posible que necesites asociar una configuración a elementos concretos de un servicio. Por ejemplo, para aplicar la autenticación en determinados métodos, pero no en otros. Para configurar esto en la configuración de tu servicio, algunas partes de la configuración del servicio, como authentication y http, te permiten especificar reglas y selectores. Un selector identifica los elementos del servicio, como un nombre de método al que se aplica la configuración asociada a la regla.

Un selector es una lista separada por comas de nombres cualificados definidos en el servicio: método, mensaje, campo, enum o valores de enum. El último segmento del nombre puede ser el comodín *, que coincide con cualquier sufijo. Los comodines solo se pueden usar al final de un nombre y solo para un segmento completo del nombre. Por ejemplo, foo.* es correcto, pero no foo.b* ni foo.*.bar. Para configurar un valor predeterminado para todos los elementos aplicables, especifica * por sí solo.

Ejemplo 1 (afecta a todo el servicio):

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

Ejemplo 2 (afecta a un solo método):

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

En el ejemplo anterior se muestra cómo requerir la validación de la clave de API para todos los métodos, excepto el método ListShelves.

Las reglas se evalúan de forma secuencial y se aplica la última que coincida en el orden de declaración.

Usar varios archivos YAML

Puede que te resulte útil usar más de un archivo YAML para configurar diferentes funciones del mismo servicio. Si usas varios archivos YAML, te resultará más fácil reutilizar archivos y modificarlos para diferentes entornos. Por ejemplo, en el ejemplo de librería, la configuración básica se especifica en el archivo api_config.yaml y sus reglas HTTP se especifican en el archivo api_config_http.yaml. De esta forma, puedes implementar las reglas HTTP solo si quieres activar la transcodificación de JSON/HTTP a gRPC para Bookstore.

Si usas varios archivos YAML para la configuración de tu servicio, cuando se despliega la configuración, cada archivo se convierte en mensajes proto google.api.Service y, a continuación, todos los mensajes se combinan mediante la semántica de combinación de proto. Es decir, todos los campos escalares singulares de la última instancia sustituyen a los de la primera. Por lo tanto, si proporciona valores únicos diferentes para la misma regla en dos archivos, se utilizará el valor del segundo archivo que especifique al implementar la configuración. Los mensajes insertados singulares se combinan y los campos repetidos se concatenan.

Al igual que las reglas, la combinación depende del orden. Si hay dos configuraciones de servicio, la segunda anula la primera.

Anotaciones (solo reglas HTTP)

Como alternativa a usar un archivo YAML para configurar las opciones HTTP, puedes configurarlas directamente en el archivo proto mediante el mecanismo de opciones. Las anotaciones de la API se definen en annotations.proto.

Usa anotaciones si la opción de configuración debe ser invariable en todos los usos de la definición de interfaz de búfer de protocolo. Por ejemplo, si una API tiene una sola implementación o todas las implementaciones deben tener la misma interfaz HTTP, puedes anotar la configuración HTTP en el archivo proto.

Si se proporciona una opción de configuración tanto en el archivo proto como en el archivo YAML de configuración del servicio, la configuración del servicio anula la anotación.

Ejemplo de anotación en un archivo 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'

Para obtener más información, consulta el artículo sobre la transcodificación de HTTP/JSON a gRPC.

Siguientes pasos