Como configurar um serviço gRPC

Para criar um serviço gRPC, usando ou não o Cloud Endpoints, especifique a definição da interface em um ou mais arquivos proto, arquivos de texto com a extensão .proto. Em um arquivo proto, defina a superfície da API, incluindo as estruturas de dados, métodos, parâmetros de método e tipos de retorno. Em seguida, compile o arquivo proto usando o compilador de buffer de protocolo específico para a linguagem, protoc. Para mais informações, consulte O que é o gRPC? e Conceitos de gRPC.

Para que o serviço gRPC seja gerenciado pelo Endpoints, 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, especifique as informações básicas sobre o serviço, como nome e título. Configure outros aspectos do serviço nas subseções do arquivo YAML. Veja alguns exemplos:

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

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

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

O esquema oficial para a configuração do serviço é definido pela mensagem .proto google.api.Service.

Configuração básica

A amostra Bookstore, usada nos tutoriais do gRPC, inclui um arquivo de definição de interface básico e um de configuração de serviço.

Definição da interface da 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;
}

Configuração do serviço da Bookstore, api_config.yaml:

type: google.api.Service
config_version: 3

name: bookstore.endpoints.MY_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 bookstore.endpoints.MY_PROJECT_ID.cloud.goog, em que MY_PROJECT_ID representa o ID do projeto do Google Cloud Platform;
  • especifica que o serviço expõe a API endpoints.examples.bookstore.Bookstore, conforme definido no arquivo bookstore.proto;
  • fornece um título descritivo exibido na página Endpoints > Serviços no Console do Google Cloud Platform após a implantação da configuração. Para comentários mais detalhados, revise as versões completas de cada arquivo no GitHub.

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 fazer isso na configuração de serviço, algumas partes dela, 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.* funciona, mas foo.b* ou foo.*.bar não. 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 validação da 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.

Como 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, na amostra Bookstore, a configuração básica é especificada no arquivo api_config.yaml e as regras HTTP são especificadas no arquivo api_config_http.yaml. Isso só permite implantar as regras de HTTP se você quiser ativar o JSON/HTTP para transcodificação de gRPC para a Bookstore.

Ao usar vários arquivos YAML para a configuração de serviço, quando ela for implantada, cada um deles será convertido em google.api.Service, e todas as mensagens serão mescladas usando a 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. As anotações da API estão definidas em annotations.proto.

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 se todas as implementações precisarem da mesma interface HTTP, será possível anotar a configuração 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.

Exemplo de anotação 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.

Validação de configuração

Implante a configuração do serviço e arquivos proto compilados usando o gcloud endpoints services deploy para criar a configuração do ambiente de execução do serviço. O comando gcloud endpoints services deploy valida a configuração do serviço e sinaliza quaisquer erros e avisos.

Os avisos são divididos em regulares e linter. Os avisos linter usam um identificador no formato <group>-<rule>, em que <group> indica o grupo de configuração e <rule> a regra linter específica. Por exemplo, abaixo do grupo está versioning e a regra é http-version-prefix:

WARNING: bookstore.proto:51:3: (lint) versioning-http-version-prefix: method
'endpoints.examples.bookstore.BookStore.ListShelves' has a different version
prefix in HTTP path ('v2') than api version 'v1'.

Para suprimir avisos linter, basta adicionar uma diretiva à documentação de um elemento da API. Isso pode ser feito no arquivo proto ou YAML da configuração de serviço. Por exemplo, o aviso acima é suprimido da seguinte maneira:

service Bookstore {
  // Returns an object.
  // (== suppress_warning versioning-http-version-prefix ==)
  rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) {
      option (google.api.http) = { get: "/v1/shelves" };
  }
}

Para suprimir avisos de todo um grupo, use um caractere curinga (*) em vez de nomes de regras. Por exemplo, versioning-* suprime todos os avisos relacionados ao grupo versioning.

As diretivas de supressão anexadas a elementos pai também se aplicam a todos os elementos secundários. Por exemplo, no caso a seguir, são suprimidos todos os avisos do grupo versioning em todos os métodos dentro do serviço:

// (== suppress_warning versioning-* ==)
service Bookstore {
  // Returns an object.
  rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) {
      option (google.api.http) = { get: "/v1/shelves" };
  }
}

Para suprimir globalmente um aviso, anexe-o à documentação geral da configuração do serviço:

type: google.api.Service
name: your_api.endpoints.<producer-project-id>.cloud.goog
title: Bookstore gRPC API
apis:
- name: endpoints.examples.bookstore.BookStore
documentation:
    overview: |
      A simple Bookstore gRPC API.
      (== suppress_warning documentation-presence ==)

Observe que as diretivas na documentação, como suppress_warning, precisam aparecer na própria linha, caso contrário, não serão reconhecidas. Marcadores literais em bloco do YAML, como >, removem todas as novas linhas. Assim, se o overview: > for usado no exemplo anterior, a supressão não funcionará. Para mais informações sobre literais em bloco do YAML, consulte Delimitação recuada.

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Cloud Endpoints com gRPC
Precisa de ajuda? Acesse nossa página de suporte.