gRPC descriptors

Cloudstate entities specify their interfaces using gRPC descriptors. The following example descriptor provides a shopping cart entity. It supports three different commands, AddItem, RemoveItem and GetCart.

syntax = "proto3";

import "google/protobuf/empty.proto";
import "cloudstate/entity_key.proto";

package example.shoppingcart;

service ShoppingCartService {
    rpc AddItem(AddLineItem) returns (google.protobuf.Empty);
    rpc RemoveItem(RemoveLineItem) returns (google.protobuf.Empty);
    rpc GetCart(GetShoppingCart) returns (Cart);

message AddLineItem {
    string user_id = 1 [(.cloudstate.entity_key) = true];
    string product_id = 2;
    string name = 3;
    int32 quantity = 4;

message RemoveLineItem {
    string user_id = 1 [(.cloudstate.entity_key) = true];
    string product_id = 2;

message GetShoppingCart {
    string user_id = 1 [(.cloudstate.entity_key) = true];

message LineItem {
    string product_id = 1;
    string name = 2;
    int32 quantity = 3;

message Cart {
    repeated LineItem items = 1;

Specifying the entity key

The most important thing to note in the above descriptor is the entity key annotations. Each message that is used as the input of an rpc command has one - this is a requirement of Cloudstate, all inbound command messages must contain an entity key.

The entity key is used by Cloudstate to know which instance of an entity a command is for. In the above example, the entity key used is the user_id. This means, there will be one shopping cart entity for each user_id in the system. When a command is received for a given entity key, Cloudstate will establish a gRPC streamed call to the user function using that entity’s type’s protocol if one isn’t already established, and any commands received for the entity key will be sent through that call.

Cloudstate entity keys must be strings. When a non string type is specified as the entity key, it is converted to a string in a proxy specific manner. It’s recommended therefore, for maximum portability, that only strings are used as entity keys. If more than one field is specified as an entity key, the fields are concatenated together in a proxy specific manner.

Transcoding HTTP

Cloudstate proxies support transcoding gRPC to HTTP/JSON, using the Google transcoding annotations described here. Using this, you can consume your entities' gRPC interfaces using HTTP/JSON.