Configura un servicio de gRPC

Para crear un servicio gRPC, ya sea que uses API Gateway o no, especifica la definición de la interfaz en uno o más archivos proto, que son archivos de texto con la extensión .proto. En un archivo proto, defines la superficie de la API, incluidas las estructuras de datos, los métodos, los parámetros de los métodos y los tipos de datos que se muestran. Luego, compilas tu archivo proto mediante el uso del compilador de búfer de protocolo específico del lenguaje, protoc. Si deseas obtener más información, consulta ¿Qué es gRPC? y Conceptos de gRPC.

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

Descripción general de la configuración del servicio

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

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 corresponde, por lo general, a un mensaje .proto, en el que configuras varios aspectos del servicio. Por ejemplo:

  • authentication: especifica cómo se autentican los emisores.
  • backend: controla el enrutamiento del backend remoto.
  • http: define las reglas para asignar un método RPC a uno o más métodos de la API de REST HTTP.
  • usage te permite habilitar o inhabilitar de manera selectiva la validación de la clave de API.

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

Configuración básica

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

La definición de la interfaz de Libreria, 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;
}

La configuración del servicio de la Librería, 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

La muestra del código previa es la configuración del servicio más simple, ya que:

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

Reglas y selectores

En algunos casos, es posible que necesites la capacidad de asociar la configuración con elementos individuales de un servicio, por ejemplo, para aplicar la autenticación en ciertos métodos, pero no en otros. A fin de configurar esto en la configuración de tu servicio, algunas partes de la configuración del servicio, como authentication y http, te permiten especificar las reglas y los selectores. Un selector identifica los elementos del servicio, como el nombre del método al que se aplica la configuración asociada con la regla.

Un selector es una lista separada por comas de nombres calificados definidos en el servicio: método, mensaje, campo, enumeración o valores de enumeración. El último segmento del nombre puede ser el comodín *, que coincide con cualquier sufijo. Los comodines se permiten solo al final de un nombre y solo para un segmento completo del nombre. Por ejemplo: foo.* está bien, pero no foo.b* o foo.*.bar. A fin de configurar un valor predeterminado para todos los elementos aplicables, especifica * por su cuenta.

Ejemplo 1 (afecta a todo el servicio):

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

Ejemplo 2 (afecta solo a un 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 para el ListShelves.

Las reglas se evalúan de forma secuencial; se aplica la última que coincide con una del orden de declaración.

Cómo usar varios archivos YAML

Puede resultarte útil usar más de un archivo YAML con el fin de configurar diferentes características para el mismo servicio. El uso de varios archivos YAML facilita la reutilización de archivos y su modificación para diferentes entornos. Por ejemplo, en la Librería de muestra, la configuración básica se especifica en el archivo api_config.yaml, y sus reglas HTTP, en el archivo api_config_http.yaml. Esto te permite implementar las reglas HTTP solo si deseas activar la transcodificación de JSON/HTTP a gRPC para la Librería.

Si usas varios archivos YAML para la configuración de tu servicio, cuando se implementa la configuración, cada archivo se convierte en mensajes proto google.api.Service y, luego, todos los mensajes se combinan mediante la semántica de combinación de proto. Es decir, todos los campos escalares singulares en la última instancia reemplazan a los de la anterior. Entonces, si proporcionas valores singulares diferentes para la misma regla en dos archivos, se usa el valor en el segundo archivo que especificaste cuando implementaste la configuración. Los mensajes incorporados singulares se combinan y los campos repetidos se concatenan.

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

Anotaciones (solo reglas HTTP)

Como alternativa al uso de un archivo YAML para configurar las opciones de HTTP, puedes configurarlas directamente en tu archivo proto, mediante el uso de los mecanismos de opciones. Las anotaciones de la API se definen en annotations.proto.

Usa las anotaciones si la opción de configuración está destinada a ser invariante en todos los usos de la definición de la interfaz del búfer de protocolo. Por ejemplo, si una API tiene una sola implementación o es necesario que todas las implementaciones tengan 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 Transcodificar HTTP/JSON a gRPC.

¿Qué sigue?