Manage your gRPC APIs with Google Cloud Endpoints



For the last two years, we at Google have put heavy investment in gRPC  in both the open source framework itself and in our own gRPC-based APIs. We see it as an essential component for microservices, but also for many public-facing APIs (especially those with low latency tolerance, the need for bi-directional streaming or heavy mobile use). And now, you can define and run a gRPC API and serve both gRPC and JSON-HTTP/1.1 to your clients using Google Cloud Endpoints!

Most of the APIs that we’ve released recently serve both a gRPC and an HTTP/1.1-JSON interface. Starting with Cloud Pub/Sub release in March 2016, we’ve announced a steady stream of APIs that use gRPC: Cloud Bigtable, Cloud Pub/Sub, Cloud Vision API, Cloud Datastore, Cloud Speech API and of course the recently announced Cloud Spanner API among others.

Serving a gRPC interface gives us the latency and bandwidth characteristics we need at scale and ensures all clients are using a compatible client library.

However, we still serve a JSON-HTTP/1.1 interface for these APIs. Why? Well, millions of developers are comfortable with JSON. It offers a really easy getting started experience (call it with curl, or just paste a request into any browser). There are great JSON libraries in every language available on essentially every platform. So even though the world is moving to gRPC for APIs that require streaming and high performance, supporting JSON-HTTP/1.1 remains a high priority.

Now you too can offer both gRPC and JSON-HTTP/1.1 for your APIs. Cloud Endpoints fully supports gRPC-based APIs (including all the same great Endpoints features it offers for HTTP/1.1 APIs: authentication, monitoring, logging, tracing, API keys, etc). And the Extensible Service Proxy will also translate JSON-HTTP/1.1 calls, so you can write your API once and serve both interfaces.

Getting started is simple. Define a gRPC service using a .proto file, then add a YAML config file to map that gRPC interface to REST JSON.

For example, you may have a simple service that defines a Bookshelf:
import "google/protobuf/empty.proto";

// A simple Bookstore API.
//
// The API manages shelves and books resources. Shelves contain books.
service Bookstore {
  // Returns a list of all shelves in the bookstore.
  rpc CreateShelf(CreateShelfRequest) returns (Shelf) {}
  // Returns a specific bookstore shelf.
  rpc GetShelf(GetShelfRequest) returns (Shelf) {}
}

// A shelf resource.
message Shelf {
  // A unique shelf id.
  int64 id = 1;
  // A theme of the shelf (fiction, poetry, etc).
  string theme = 2;
}

// Request message for CreateShelf method.
message CreateShelfRequest {
  // The shelf resource to create.
  Shelf shelf = 1;
}

// Request message for GetShelf method.
message GetShelfRequest {
  // The ID of the shelf resource to retrieve.
  int64 shelf = 1;
}

Your service configuration YAML tells Endpoints how to map that RPC interface to RESTful paths:

code>type: google.api.Service
config_version: 3

name: bookstore.endpoints..cloud.goog

title: Bookstore gRPC API
apis:
- name: endpoints.examples.bookstore.Bookstore


Http:
  rules:
  # 'CreateShelf' can be called using the POST HTTP verb and the '/shelves' URL
  # path. The posted HTTP body is the JSON respresentation of the 'shelf' field
  # of 'CreateShelfRequest' protobuf message.
  #
  # Client example:
  #   curl -d '{"theme":"Music"}' http://DOMAIN_NAME/v1/shelves
  #
  - selector: endpoints.examples.bookstore.Bookstore.CreateShelf
    post: /v1/shelves
    body: shelf
  #
  # 'GetShelf' is available via the GET HTTP verb and '/shelves/{shelf}' URL
  # path, where {shelf} is the value of the 'shelf' field of 'GetShelfRequest'
  # protobuf message.
  #
  # Client example - returns the first shelf:
  #   curl http://DOMAIN_NAME/v1/shelves/1
  #
  - selector: endpoints.examples.bookstore.Bookstore.GetShelf
    get: /v1/shelves/{shelf}

Your service configuration YAML can also specify authentication (for example, only permit a specified service account to call the API):

#
# Request authentication.
#
authentication:
  providers:
  - id: google_service_account
    # Replace SERVICE-ACCOUNT-ID with your service account's email address.
    issuer: SERVICE-ACCOUNT-ID
    jwks_uri: https://www.googleapis.com/robot/v1/metadata/x509/SERVICE-ACCOUNT-ID
  rules:
  # This auth rule will apply to all methods.
  - selector: "*"
    requirements:
      - provider_id: google_service_account

For full docs on how to create the transcoding mapping, see the docs at https://cloud.google.com/endpoints/docs/transcoding.

We have gRPC/Endpoints samples in four different languages: Python, Go, Java and Node.js. Better yet, we’ve got lots of customers using gRPC and Endpoints together already. So try the sample, head over to our Google Group to ask a question, and go make APIs!