gRPC 서비스 구성

API 게이트웨이를 사용하는지 여부에 관계없이 gRPC 서비스를 만들려면 하나 이상의 proto 파일(확장자가 .proto인 텍스트 파일)에 인터페이스 정의를 지정해야 합니다. proto 파일에서 데이터 구조, 메서드, 메서드 매개변수, 반환 유형을 포함하여 API의 노출 영역을 정의합니다. 그런 다음 언어별 프로토콜 버퍼 컴파일러인 protoc을 사용하여 proto 파일을 컴파일합니다. 자세한 내용은 gRPC란?gRPC 개념을 참조하세요.

gRPC 서비스를 API 게이트웨이가 관리하도록 하려면 컴파일된 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 게이트웨이 및 gRPC용 Cloud Run 시작하기 튜토리얼에 사용되는 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에 대해 gRPC로 JSON/HTTP 트랜스코딩을 사용 설정하려는 경우에만 HTTP 규칙을 배포할 수 있습니다.

서비스 구성에 여러 YAML 파일을 사용하려는 경우 구성이 배포될 때 각 파일이 google.api.Service proto 메시지로 변환된 후 proto 병합 시맨틱스를 사용하여 모든 메시지가 병합됩니다. 즉, 이후 인스턴스의 모든 단일 스칼라 필드가 이전 인스턴스의 단일 스칼라 필드를 대체합니다. 따라서 두 파일의 동일한 규칙에 대해 서로 다른 단일 값을 제공하면 구성을 배포할 때 지정한 두 번째 파일의 값이 사용됩니다. 단일 포함 메시지는 병합되고, 반복되는 필드는 연결됩니다.

규칙과 마찬가지로 병합은 순서대로 이루어집니다. 2개의 서비스 구성이 있는 경우 두 번째 서비스 구성이 첫 번째 구성을 재정의합니다.

주석(HTTP 규칙만)

HTTP 옵션 구성에 YAML 파일을 사용하는 대신 옵션 메커니즘을 사용하여 proto 파일에 직접 HTTP 옵션을 구성할 수 있습니다. API 주석은 annotations.proto에 정의됩니다.

구성 옵션이 프로토콜 버퍼 인터페이스 정의 모든 용도에 대해 불변인 경우 주석을 사용합니다. 예를 들어 API에 단일 구현이 있거나 모든 구현에 동일한 HTTP 인터페이스가 있어야 하는 경우 HTTP 구성을 proto 파일에 주석으로 추가할 수 있습니다.

구성 옵션이 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'

자세한 내용은 gRPC로 HTTP/JSON 트랜스코딩을 참조하세요.

다음 단계