Configurazione di un servizio gRPC

Per creare un servizio gRPC, indipendentemente dal fatto che utilizzi API Gateway, devi specificare la definizione dell'interfaccia in uno o più proto file, che sono file di testo con estensione .proto. In un file proto, definisci la superficie dell'API, compresi le strutture di dati, i metodi, i parametri dei metodi e i tipi di ritorno. Poi devi compilare il tuo file proto utilizzando il compilatore del buffer di protocollo specifico per la lingua, protoc. Per ulteriori informazioni, consulta Che cos'è gRPC? e concetti di gRPC.

Per fare in modo che il servizio gRPC venga gestito da API Gateway, oltre al file di protocollo compilato, devi specificare una configurazione del servizio in uno o più file YAML. Una configurazione del servizio è una specifica che consente di definire il comportamento di un servizio gRPC, incluse autenticazione, quote e altro.

Panoramica della configurazione del servizio

Nella parte superiore del file YAML puoi specificare informazioni di base sul servizio, come il nome e il titolo. Altri aspetti del servizio sono configurati nelle sezioni secondarie del file YAML, ad esempio:

Ad esempio:

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

Ogni sottosezione corrisponde in genere a un messaggio .proto in cui configuri i vari aspetti del servizio. Ad esempio:

  • authentication: specifica come vengono autenticati i chiamanti.
  • backend: controlla il routing del backend remoto.
  • http: definisce le regole per la mappatura di un metodo RPC a uno o più metodi dell'API REST HTTP.
  • usage: consente di abilitare e disabilitare in modo selettivo la convalida delle chiavi API.

Lo schema ufficiale per la configurazione del servizio è definito dal messaggio .proto google.api.Service.

Configurazione di base

L'esempio di Bookstore, utilizzato nel tutorial Introduzione a API Gateway e Cloud Run for gRPC, include un file di definizione dell'interfaccia di base e un file di configurazione del servizio.

Definizione dell'interfaccia 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;
}

La configurazione del servizio Libreria, 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

L'esempio di codice precedente è la configurazione del servizio più semplice, in quanto:

  • Definisce un servizio denominato *.apigateway.PROJECT_ID.cloud.goog dove PROJECT_ID è il nome del tuo ID progetto Google Cloud.
  • Specifica che il servizio espone l'API endpoints.examples.bookstore.Bookstore, come definito nel file bookstore.proto.

Regole e selettori

In alcuni casi, potrebbe essere necessaria la possibilità di associare la configurazione a singoli elementi di un servizio, ad esempio per applicare l'autenticazione su determinati metodi e non su altri. Per configurarlo nella configurazione del servizio, alcune parti della configurazione del servizio, come authentication e http, consentono di specificare regole e selettori. Un selettore identifica gli elementi del servizio, ad esempio un nome del metodo a cui si applica la configurazione associata alla regola.

Un selettore è un elenco separato da virgole di nomi qualificati definiti nel servizio: valori di metodo, messaggio, campo, enum o enum. L'ultimo segmento del nome può essere il carattere jolly *, che corrisponde a qualsiasi suffisso. I caratteri jolly sono consentiti solo alla fine di un nome e solo per un intero segmento del nome. Ad esempio: foo.* va bene, ma non foo.b* o foo.*.bar. Per configurare un valore predefinito per tutti gli elementi applicabili, devi specificare * da solo.

Esempio 1 (interessato all'intero servizio):

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

Esempio 2 (che interessa un singolo metodo):

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

L'esempio precedente mostra come richiedere la convalida delle chiavi API per tutti i metodi tranne il metodo ListShelves.

Le regole vengono valutate in sequenza e viene applicata l'ultima corrispondenza nell'ordine di dichiarazione.

Utilizzo di più file YAML

Potresti trovare utile utilizzare più file YAML per configurare funzionalità diverse per lo stesso servizio. Usare più file YAML semplifica il riutilizzo dei file e la loro modifica per ambienti diversi. Ad esempio, nell'esempio di Bookstore, la configurazione di base è specificata nel file api_config.yaml e le relative regole HTTP sono specificate nel file api_config_http.yaml. In questo modo puoi eseguire il deployment delle regole HTTP solo se vuoi attivare la transcodifica da JSON/HTTP a gRPC per il Bookstore.

Se utilizzi più file YAML per la configurazione del servizio, quando la configurazione viene implementata, ogni file viene convertito in messaggi proto google.api.Service e tutti i messaggi vengono uniti utilizzando la semantica dell'unione dei proto. Ciò significa che tutti i campi scalari singolari dell'ultima istanza sostituiscono quelli della precedente. Pertanto, se fornisci valori singolari diversi per la stessa regola in due file, viene utilizzato il valore nel secondo file specificato durante il deployment della configurazione. I messaggi incorporati singolari vengono uniti e i campi ripetuti vengono concatenati.

Come per le regole, l'unione è sensibile all'ordine. Se esistono due configurazioni di servizio, la seconda configurazione del servizio#39;override della prima.

Annotazioni (solo regole HTTP)

In alternativa all'utilizzo di un file YAML per la configurazione delle opzioni HTTP, puoi configurarle direttamente nel file proto, utilizzando il meccanismo delle opzioni. Le annotazioni API sono definite in annotations.proto.

Utilizza le annotazioni se l'opzione di configurazione deve essere invariante rispetto a tutti gli utilizzi della definizione dell'interfaccia del buffer di protocollo. Ad esempio, se un'API ha un'unica implementazione o se tutte le implementazioni devono avere la stessa interfaccia HTTP, puoi annotare la configurazione HTTP nel file proto.

Se viene fornita un'opzione di configurazione, sia nel file proto sia nel file YAML di configurazione del servizio, la configurazione del servizio sostituisce l'annotazione.

Esempio di annotazione in un file 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'

Per maggiori informazioni, consulta Transcodifica di HTTP/JSON in gRPC.

Passaggi successivi