Para criar um serviço gRPC, quer esteja ou não a usar o Cloud Endpoints, tem de especificar a definição da interface num ou mais ficheiros proto
, que são ficheiros de texto com a extensão .proto
. Num ficheiro proto
, define a superfície da sua API, incluindo as estruturas de dados, os métodos, os parâmetros dos métodos e os tipos de retorno. Em seguida, compila o ficheiro proto
com o compilador de buffers de protocolo específico do idioma, protoc
. Para mais informações, consulte os artigos
O que é o gRPC?
e
Conceitos do gRPC.
Para que o seu serviço gRPC seja gerido pelos Endpoints, além do ficheiro proto compilado, tem de especificar uma configuração do serviço num ou mais ficheiros YAML. Uma configuração de serviço é uma especificação que lhe permite definir o comportamento de um serviço gRPC, incluindo autenticação, quotas e muito mais.
Vista geral da configuração do serviço
Na parte superior do ficheiro YAML, especifica informações básicas sobre o serviço, como o nome e o título. Configura outros aspetos do serviço em subseções do ficheiro YAML, por exemplo:
- Que APIs são publicadas.
- Como os autores das chamadas são autenticados.
- Como restringir ou conceder acesso à API com chaves da API.
- Como as APIs são acedidas através de HTTP REST.
- Para APIs que usam o domínio
cloud.goog
, a configuração de DNS.
Por 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 subsecção corresponde a uma mensagem .proto
onde configura vários aspetos do serviço. Por exemplo:
authentication
: especifica como os autores das chamadas são autenticados.backend
: controla o encaminhamento do back-end remoto.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 da API.
O esquema oficial da configuração do serviço é definido pela .proto
mensagem
google.api.Service
.
Configuração básica
O exemplo da livraria, que é usado nos tutoriais de gRPC, inclui um ficheiro de definição de interface básico e um ficheiro de configuração de serviço.
A definição da interface da livraria,
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; }
A configuração do serviço 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, uma vez que:
- Define um serviço denominado
bookstore.endpoints.MY_PROJECT_ID.cloud.goog
, ondeMY_PROJECT_ID
representa o ID do seu Google Cloud projeto. - Especifica que o serviço expõe a API
endpoints.examples.bookstore.Bookstore
, conforme definido no ficheirobookstore.proto
. - Fornece um título descritivo que aparece na página Endpoints > Serviços na Google Cloud consola depois de implementar a configuração. Reveja as versões completas do GitHub de cada ficheiro para ver comentários mais detalhados.
Regras e seletores
Em alguns casos, pode precisar da capacidade de associar a configuração a elementos individuais de um serviço, por exemplo, para aplicar a autenticação a determinados métodos, mas não a outros. Para configurar esta opção na configuração do serviço, algumas partes da configuração do serviço, como
authentication
e
http
,
permitem-lhe especificar regras e seletores. Um seletor identifica os elementos do serviço, como um nome de método ao qual a configuração associada à regra se aplica.
Um seletor é uma lista de nomes qualificados separados por vírgulas definidos no serviço:
método, mensagem, campo, enumeração ou valores de enumeração. O último segmento do nome pode ser o caráter universal *
, que corresponde a qualquer sufixo. Os carateres universais só são permitidos no final de um nome e apenas para um segmento completo do nome. Por exemplo: foo.*
é
aceitável, mas não foo.b*
nem foo.*.bar
. Para configurar um valor predefinido para todos os elementos aplicáveis, especifique *
sozinho.
Exemplo 1 (que afeta todo o serviço):
usage:
rules:
# Allow unregistered calls for all methods.
- selector: "*"
allow_unregistered_calls: true
Exemplo 2 (que 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 da chave da API para todos os métodos, exceto o método ListShelves
.
As regras são avaliadas sequencialmente e é aplicada a última regra correspondente na ordem de declaração.
Usar vários ficheiros YAML
Pode ser útil usar mais do que um ficheiro YAML para configurar diferentes funcionalidades para o mesmo serviço. A utilização de vários ficheiros YAML facilita a reutilização de ficheiros e a respetiva modificação para diferentes ambientes. Por exemplo, no exemplo da livraria, a configuração básica é especificada no ficheiro
api_config.yaml
e as respetivas regras HTTP são especificadas no ficheiro
api_config_http.yaml
. Isto permite-lhe implementar as regras HTTP apenas se quiser ativar a transcodificação JSON/HTTP para gRPC para a livraria.
Se usar vários ficheiros YAML para a configuração do serviço, quando a configuração é implementada, cada ficheiro é convertido em mensagens proto google.api.Service
e, em seguida, todas as mensagens são unidas através da semântica de união de proto.
Ou seja, todos os campos escalares singulares na última instância substituem os da primeira. Assim, se fornecer valores singulares diferentes para a mesma regra em dois ficheiros, é usado o valor no segundo ficheiro que especificar quando implementar a configuração. As mensagens incorporadas singulares são unidas e os campos repetidos são
concatenados.
Tal como as regras, a união é sensível à ordem. Se existirem duas configurações de serviço, a segunda configuração de serviço substitui a primeira.
Anotações (apenas regras HTTP)
Em alternativa à utilização de um ficheiro YAML para configurar as opções HTTP, pode configurá-las diretamente no ficheiro proto
através do 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 se destinar a ser invariante em todas as utilizações da definição da interface do buffer de protocolo. Por exemplo, se uma API tiver uma única implementação ou todas as implementações tiverem de ter a mesma interface HTTP, pode anotar a configuração HTTP no ficheiro proto
.
Se for fornecida uma opção de configuração no ficheiro proto
e no ficheiro YAML de configuração do serviço, a configuração do serviço substitui a anotação.
Exemplo de anotação num ficheiro 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 o artigo Transcodificação de HTTP/JSON para gRPC.
Validação da configuração
Implemente a configuração do serviço e os ficheiros proto
compilados usando o
gcloud endpoints services deploy
para criar a configuração do tempo 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 dividem-se em avisos normais e avisos de linter. Os avisos do Linter usam um identificador do formulário <group>-<rule>
, onde <group>
indica o grupo de configuração e <rule>
a regra do 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'.
Pode suprimir avisos do linter adicionando uma diretiva à documentação de um elemento da API. Pode adicionar a diretiva no ficheiro proto
ou no ficheiro YAML de configuração do serviço. Por exemplo, o seguinte suprime o aviso anterior:
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 para um grupo inteiro, pode usar um caráter universal (*
) em vez
dos nomes das regras. Por exemplo, versioning-*
suprime todos os avisos relacionados com o grupo versioning
.
As diretivas de supressão anexadas a elementos principais também se aplicam a todos os elementos secundários. Por exemplo, o exemplo seguinte suprime todos os versioning
avisos de grupo em todos os métodos no 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 um aviso globalmente, anexe-o à documentação de vista 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 ==)
Tenha em atenção que as diretivas na documentação, como suppress_warning
, têm de aparecer na sua própria linha. Caso contrário, não são reconhecidas. Os marcadores literais de blocos YAML, como >
, removem todas as novas linhas. Por isso, se usar overview: >
no exemplo anterior, a supressão não funciona. Para mais informações sobre literais de blocos em YAML,
consulte
Delimitação com recuo.
O que se segue?
- Configurar pontos finais
- Implementar a configuração dos Endpoints
- Referência de configuração do serviço gRPC