配置 gRPC 服务

如需创建 gRPC 服务(无论您是否在使用 API Gateway),请在一个或多个 proto 文件(即扩展名为 .proto 的文本文件)中指定接口定义。您可以在 proto 文件中定义 API 的表面,包括数据结构、方法、方法参数以及返回类型。然后,您可以使用特定于语言的协议缓冲区编译器 protoc 编译 proto 文件。如需了解详情,请参阅 gRPC 简介gRPC 概念

如需让您的 gRPC 服务由 API Gateway 管理,除了已编译的 proto 文件,您还必须在一个或多个 YAML 文件中指定“服务配置”。服务配置是一种规范,可让您定义 gRPC 服务的行为,包括身份验证、配额等。

服务配置概述

在 YAML 文件的顶部,您可以指定有关服务的基本信息,例如其名称和标题。在 YAML 文件的子部分可以配置该服务的其他方面,例如:

例如:

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

通常每个子部分对应于一个 .proto 消息,您可在其中配置服务的各个方面。例如:

  • authentication:指定如何对调用者进行身份验证。
  • backend:控制远程后端路由。
  • http:定义用于将 RPC 方法映射到一个或多个 HTTP REST API 方法的规则。
  • usage:可让您有选择性地启用和停用 API 密钥验证。

服务配置的官方架构由 .proto 消息 google.api.Service 定义。

基本配置

使用入门:API Gateway 和 Cloud Run for gRPC 教程中使用的 Bookstore 示例包含一个基本接口定义文件和一个服务配置文件。

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

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

上述代码示例是最简单的服务配置,因为它:

  • 定义名为 *.apigateway.PROJECT_ID.cloud.goog 的服务,其中的 PROJECT_ID 是您的 Google Cloud 项目 ID 的名称。
  • 指定该服务公开 bookstore.proto 文件中定义的 API endpoints.examples.bookstore.Bookstore

规则和选择器

在有些情况下,您可能需要将配置与服务的各个元素相关联,例如,对某些方法强制执行身份验证,而对其他方法不执行身份验证。如需在服务配置中对此进行配置,您可以通过 authenticationhttp 服务配置的某些部分来指定“规则”和“选择器”。选择器可标识与规则关联的配置适用的服务元素(例如方法名称)。

选择器是服务中定义的以逗号分隔的限定名称列表:方法、消息、字段、枚举或枚举值。名称的最后一部分可以是通配符 *(可与任何后缀匹配)。通配符仅可用在名称的末尾,并且只能用在完整的名称末尾。例如:foo.* 没问题,但 foo.b*foo.*.bar 则不行。如需为所有适用元素配置默认值,请单独指定 *

示例 1(影响整个服务):

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

示例 2(影响单个方法):

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

上面的示例展示如何要求对除了 ListShelves 方法之外的所有方法进行 API 密钥验证。

系统将按顺序评估规则,并会应用按声明顺序排列的最后一个匹配的规则。

使用多个 YAML 文件

您可能会发现,使用多个 YAML 文件为同一服务配置不同功能十分有用。使用多个 YAML 文件可让您更轻松地重用文件并针对不同的环境修改这些文件。例如,在 Bookstore 示例中,基本配置是在 api_config.yaml 文件中指定的,其 HTTP 规则是在 api_config_http.yaml 文件中指定的。这样一来,您可以仅在想要为 Bookstore 开启 JSON/HTTP 到 gRPC 转码时部署 HTTP 规则。

如果您使用多个 YAML 文件进行服务配置,则在您部署配置时,每个文件都将转换为 google.api.Service proto 消息,然后再通过 proto 合并语义合并所有消息。也就是说,后一实例中的所有奇异标量字段会替换前一实例中的字段。因此,如果您在两个文件中为同一规则提供不同的奇异值,则系统会使用您在部署配置时指定的第二个文件中的值。奇异嵌入式消息会合并,重复的字段也会合并。

与规则一样,合并与顺序有关。如果有两种服务配置,则第二种服务配置会替换第一种服务配置。

注释(仅限 HTTP 规则)

除了使用 YAML 文件配置 HTTP 选项外,您还可以使用选项机制直接在 proto 文件中配置这些选项。API 注释是在 annotations.proto 中定义的。

如果要将配置选项设计为在协议缓冲区接口定义的所有用法中都保持不变,请使用注释。例如,如果某个 API 只会使用一次,或者每次使用 API 时都需要具备相同的 HTTP 接口,那么您可以在 proto 文件中注释 HTTP 配置。

如果 proto 文件和服务配置 YAML 文件中都提供了配置选项,则服务配置会替换注解。

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'

如需了解详情,请参阅将 HTTP/JSON 转码为 gRPC

后续步骤