Configuring a gRPC service

To create a gRPC service—whether or not you are using Cloud Endpoints—you specify the interface definition in one or more proto files , which are text files with the .proto extension. In a proto file, you define the surface of your API, including the data structures, methods, method parameters, and return types. Then, you compile your proto file by using the language-specific protocol buffer compiler, protoc . For more information, see What is gRPC? and gRPC concepts .

To have your gRPC service managed by Endpoints, in addition to the compiled proto file, you have to specify a service configuration in one or more YAML files. A service configuration is a specification that lets you define the behavior of a gRPC service, including authentication, quotas, and more.

Service configuration overview

At the top of the YAML file, you specify basic information about the service , such as its name and title. You configure other aspects of the service in subsections of the YAML file, for example:

For example:

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

Each subsection typically corresponds to a .proto message where you configure various aspects of the service. For example:

  • authentication : specifies how callers are authenticated.
  • backend : controls remote backend routing.
  • http : defines the rules for mapping an RPC method to one or more HTTP REST API methods.
  • usage : lets you selectively enable and disable API key validation.

The official schema for the service configuration is defined by the .proto message google.api.Service .

Basic configuration

The Bookstore sample , which is used in the gRPC tutorials , includes a basic interface definition file and a service configuration file.

The Bookstore interface definition, 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 
 ; 
 } 

The Bookstore service configuration, 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 

The previous code sample is the simplest service configuration as it:

  • Defines a service named bookstore.endpoints. MY_PROJECT_ID .cloud.goog , where MY_PROJECT_ID represents your Google Cloud project ID.
  • Specifies that the service exposes the API endpoints.examples.bookstore.Bookstore , as defined in the bookstore.proto file.
  • Provides a descriptive title that appears on the Endpoints> Servicespage in the Google Cloud console after you deploy the configuration. Review the complete GitHub versions of each file for more detailed comments.

Rules and selectors

In some cases, you might need the ability to associate configuration with individual elements of a service—for example, to enforce authentication on certain methods but not others. To configure this in your service configuration, some parts of the service configuration, such as authentication and http , let you specify rules and selectors . A selector identifies the elements of the service, such as a method name that the configuration associated with the rule applies to.

A selector is a comma-separated list of qualified names defined in the service: method, message, field, enum, or enum values. The last segment of the name can be the wildcard * , which matches any suffix. Wildcards are allowed only at the end of a name and only for a whole segment of the name. For example: foo.* is okay, but not foo.b* or foo.*.bar . To configure a default for all applicable elements, you specify * by itself.

Example 1 (affecting entire service):

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

Example 2 (affecting a single method):

  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 
 

The previous example shows how to require API key validation for all methods except the ListShelves method.

Rules are evaluated sequentially, the last matching one in the declaration order is applied.

Using multiple YAML files

You might find it useful to use more than one YAML file to configure different features for the same service. Using multiple YAML files makes it easier to reuse files and modify them for different environments. For example, in the Bookstore sample, the basic configuration is specified in the api_config.yaml file and its HTTP rules are specified in the api_config_http.yaml file. This lets you deploy the HTTP rules only if you want to turn on JSON/HTTP to gRPC transcoding for the Bookstore.

If you use multiple YAML files for your service configuration, when the configuration is deployed each file is converted to google.api.Service proto messages, and then all messages are merged using proto merging semantics. That is, all singular scalar fields in the latter instance replace those in the former. So if you provide different singular values for the same rule in two files, the value in the second file you specify when deploying the configuration is used. Singular embedded messages are merged, and repeated fields are concatenated.

Like rules, merging is order sensitive. If there are two service configurations, the second service configuration overrides the first one.

Annotations (HTTP rules only)

As an alternative to using a YAML file for configuring HTTP options, you can configure them directly in your proto file, using the options mechanism . API annotations are defined in annotations.proto .

Use annotations if the configuration option is intended to be invariant over all usages of the protocol buffer interface definition. For example, if an API has one single implementation, or all implementations are required to have the same HTTP interface, you can annotate the HTTP configuration in the proto file.

If a configuration option is provided, both in the proto file and the service configuration YAML file, the service configuration overrides the annotation.

Example annotation in a proto file:

  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' 
 

For more information, see Transcoding HTTP/JSON to gRPC .

Configuration validation

You deploy your service configuration and compiled proto files by using the gcloud endpoints services deploy to create your service’s runtime configuration. The gcloud endpoints services deploy command validates the service configuration and flags any errors and warnings.

Warnings are divided into regular and linter warnings. Linter warnings use an identifier of the form <group>-<rule> , where <group> indicates the configuration group, and <rule> the particular linter rule. For example, below the group is versioning and the rule is 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' 
 . 
 

You can suppress linter warnings by adding a directive to the documentation of an API element. You can add the directive in your proto file or in the service configuration YAML file. For example, the following suppresses the previous warning:

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

To suppress warnings for an entire group, you can use a wildcard ( * ) instead of rule names. For example, versioning-* suppresses all warnings related to the versioning group.

Suppression directives attached to parent elements also apply to all children. For example, the following example suppresses all versioning group warnings on all methods within the service:

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

To globally suppress a warning, attach it to the overview documentation of the service configuration:

  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 
  
 ==) 
 

Note that directives in documentation such as suppress_warning must appear on their own line, otherwise they won't be recognized. YAML block literal markers such as > remove all newlines, so if you use overview: > in the previous example, the suppression doesn't work. For more information on block literals in YAML, see Indented delimiting .

What's next

Create a Mobile Website
View Site in Mobile | Classic
Share by: