Configurar um serviço gRPC

Para criar um serviço gRPC, mesmo que você não use o gateway de API, você especifica a definição da interface em um ou mais proto arquivos, que são arquivos de texto com a extensão .proto. Em um arquivo proto, você define a superfície da API, incluindo as estruturas de dados, os métodos, os parâmetros do método e os tipos de retorno. Em seguida, compile seu arquivo proto usando o compilador de buffer de protocolo específico da linguagem, protoc. Para mais informações, consulte O que é gRPC? e Conceitos de gRPC (links em inglês).

Para que o serviço gRPC seja gerenciado pelo gateway de API, além do arquivo proto compilado, é preciso especificar uma configuração de serviço em um ou mais arquivos YAML. Uma configuração de serviço é uma especificação que permite definir o comportamento de um serviço gRPC, incluindo autenticação, cotas e muito mais.

Visão geral da configuração de serviço

Na parte superior do arquivo YAML, é possível especificar informações básicas sobre o serviço, como nome e título. Outros aspectos do serviço são configurados em subseções do arquivo YAML, por exemplo:

Exemplo:

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

Normalmente, cada subseção corresponde a uma mensagem .proto (em inglês), em que vários aspectos do serviço são configurados. Exemplo:

  • authentication: especifica como os chamadores são autenticados.
  • backend: controla o roteamento remoto de back-end.
  • http: define as regras para mapear um método RPC para um ou mais métodos da API REST HTTP.
  • usage: permite ativar e desativar seletivamente a validação da chave de API.

O esquema oficial das configurações de serviço é definido pela .proto mensagem google.api.Service.

Configuração básica

O exemplo do Bookstore, usado no tutorial Primeiros passos com o gateway de API e o Cloud Run para gRPC, inclui um arquivo de definição de interface básico e um arquivo de configuração de serviço.

A definição da interface Bookstore, bookstore.proto (em inglês):

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

As configurações de serviço do 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

O exemplo de código anterior é a configuração de serviço mais simples, já que:

  • Define um serviço chamado *.apigateway.PROJECT_ID.cloud.goog em que PROJECT_ID é o nome do seu Google Cloud ID do projeto.
  • especifica que o serviço expõe a API endpoints.examples.bookstore.Bookstore, conforme definido no arquivo bookstore.proto;

Regras e seletores

Em alguns casos, será preciso associar a configuração a elementos individuais de um serviço. Por exemplo, para impor a autenticação em determinados métodos, mas não em outros. Para configurar isso nas configurações de serviço, algumas partes das configurações de serviço, como authentication e http, permitem especificar regras e seletores. Um seletor identifica os elementos do serviço, como um nome de método a que a configuração associada à regra se aplica.

Um seletor é uma lista separada por vírgulas de nomes qualificados de serviço, método, mensagem, campo, "enum" ou valores de "enum". O último segmento do nome pode ser o caractere curinga *, que corresponde a qualquer sufixo. Caracteres curinga são permitidos apenas no final de um nome e apenas para um segmento inteiro do nome. Por exemplo: foo.* está correto, mas não foo.b* ou foo.*.bar. Para configurar um padrão para todos os elementos aplicáveis, especifique * por si só.

Exemplo 1 (afeta todo o serviço):

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

Exemplo 2 (afeta um único 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

O exemplo anterior mostra como exigir a validação de chave de API para todos os métodos, exceto o ListShelves.

As regras são avaliadas sequencialmente, o último correspondente na ordem de declaração é aplicado.

Cotas

Para aplicar uma cota ao serviço gRPC, defina as métricas na seção metrics de nível superior da configuração de serviço, os limites em quota.limits, e o custo de cada método em quota.metric_rules. Exemplo:

metrics:
  - name: "read-requests"
    display_name: "Read requests"
    value_type: INT64
    metric_kind: DELTA
quota:
  limits:
    - name: "read-limit"
      metric: "read-requests"
      unit: "1/min/{project}"
      values:
        STANDARD: 1000
  metric_rules:
    - selector: "endpoints.examples.bookstore.Bookstore.ListShelves"
      metric_costs:
        "read-requests": 1

Para instruções detalhadas sobre cada um desses campos, consulte o documento do Cloud Endpoints em Como configurar cotas.

Usar vários arquivos YAML

Pode ser útil usar mais de um arquivo YAML para configurar recursos diferentes para o mesmo serviço. O uso de vários arquivos YAML facilita a reutilização e modificação de arquivos para diferentes ambientes. Por exemplo, no exemplo do Bookstore, a configuração básica é especificada no arquivo api_config.yaml e suas regras HTTP estão no arquivo api_config_http.yaml (links em inglês). Isso só permite implantar as regras de HTTP se você quiser ativar o JSON/HTTP para transcodificação de gRPC para a Bookstore.

Se você usar vários arquivos YAML para as configurações de serviço, quando a configuração for implantada cada arquivo será convertido em google.api.Service mensagens proto, e então todas as mensagens serão mescladas usando semântica de mesclagem proto. Ou seja, todos os campos escalares singulares da última instância substituirão os da primeira. Portanto, ao fornecer diferentes valores singulares para a mesma regra em dois arquivos, o valor no segundo arquivo especificado ao implantar a configuração será usado. Mensagens incorporadas singulares serão mescladas e campos repetidos serão concatenados.

Assim como as regras, a mesclagem é sensível à ordem. Se houver duas configurações de serviço, a segunda substituirá a primeira.

Anotações (apenas regras HTTP)

Em vez de usar um arquivo YAML para configurar as opções de HTTP, é possível fazer isso diretamente no arquivo proto, usando o mecanismo de opções (em inglês). As anotações da API estão definidas em annotations.proto (em inglês).

Use anotações se a opção de configuração for invariável ao longo de todos os usos da definição de interface do buffer de protocolo. Por exemplo, se uma API tiver uma única implementação ou todas as implementações forem obrigadas a ter a mesma interface HTTP, anote a configuração de HTTP no arquivo proto.

Se uma opção de configuração for fornecida, tanto no arquivo proto quanto no YAML da configuração de serviço, ela substituirá a anotação.

Anotação de exemplo em um arquivo 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 mais informações, consulte Como transcodificar HTTP/JSON para gRPC.

A seguir