Skip to main content
Version: Config V1 (legacy)

gRPC

The ConfigCat Proxy can communicate over gRPC, an open-source, high-performance RPC framework with client support in several languages.

To establish gRPC connections, you'll need the protobuf and the gRPC service definition. It's required to generate clients with protoc for your desired platform.

flag_service.proto
syntax = "proto3";

option go_package = "github.com/configcat/configcat-proxy/grpc/proto";

package configcat;

import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

// Service that contains feature flag evaluation procedures.
service FlagService {
// Stream for getting notified when a feature flag's value changes.
rpc EvalFlagStream(EvalRequest) returns (stream EvalResponse) {}
// Stream for getting notified when any feature flag's value changes.
rpc EvalAllFlagsStream(EvalRequest) returns (stream EvalAllResponse) {}

// Evaluates a feature flag.
rpc EvalFlag(EvalRequest) returns (EvalResponse) {}
// Evaluates each feature flag.
rpc EvalAllFlags(EvalRequest) returns (EvalAllResponse) {}
// Requests the keys of each feature flag.
rpc GetKeys(KeysRequest) returns (KeysResponse) {}
// Commands the underlying SDK to refresh its evaluation data.
rpc Refresh(RefreshRequest) returns (google.protobuf.Empty) {}
}

// Feature flag evaluation request message.
message EvalRequest {
// The SDK identifier.
string sdk_id = 1;
// The feature flag's key to evaluate.
string key = 2;
// The User Object.
map<string, UserValue> user = 3;
}

// Feature flag evaluation response message.
message EvalResponse {
// The evaluated value.
oneof value {
int32 int_value = 1;
double double_value = 2;
string string_value = 3;
bool bool_value = 4;
}
// The variation ID.
string variation_id = 5;
}

// Response message that contains the evaluation result of each feature flag.
message EvalAllResponse {
// The evaluated value of each feature flag.
map<string, EvalResponse> values = 1;
}

// Request message for getting each available feature flag's key.
message KeysRequest {
// The SDK identifier.
string sdk_id = 1;
}

// Response message that contains each available feature flag's key.
message KeysResponse {
// The keys of each feature flag.
repeated string keys = 1;
}

// Request message for the given SDK to refresh its evaluation data.
message RefreshRequest {
// The SDK identifier.
string sdk_id = 1;
}

// Defines the possible values that can be set in the `user` map.
message UserValue {
oneof value {
double number_value = 1;
string string_value = 2;
google.protobuf.Timestamp time_value = 3;
StringList string_list_value = 4;
}
}

// Represents a list of strings.
message StringList {
repeated string values = 1;
}
info

In order to secure the gRPC communication with the Proxy, set up TLS.

Client Usage

The following example uses a generated Go client, but gRPC clients generated for other languages are working as well.

example.go
opts := []grpc.DialOption{
grpc.WithBlock(),
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
// Any TLS options
})),
}

conn, err := grpc.DialContext(context.Background(),
"localhost:50051", // Proxy host and gRPC port
opts...)
if err != nil {
panic(err)
}

defer func() {
_ = conn.Close()
}()

client := proto.NewFlagServiceClient(conn)

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

resp, err := client.EvalFlag(ctx, &proto.EvalRequest{
SdkId: "my_sdk",
Key: "<flag-key>",
User: map[string]*proto.UserValue{"Identifier": {Value: &proto.UserValue_StringValue{StringValue: "<user-id>"}}}
})
if err != nil {
panic(err)
}

fmt.Printf("Evaluation result: %v", resp.GetBoolValue())

Health Check

The Proxy exposes health information over a standardized health RPC service.

Clients can set "" as the service parameter (or skip specifying it) to get the health status of the gRPC server. Exposing the health check service is configurable and turned on by default.

For more details about gRPC health checking, check out the official documentation.

Server Reflection

The Proxy can expose its protobuf-defined feature flag evaluation API over a standardized reflection RPC service, including all types referenced by the request and response messages. Exposing the reflection service is configurable and turned off by default.

For more details about gRPC server reflection, check out the official documentation.

Available Options

The following gRPC related options are available:

options.yml
grpc:
enabled: <true|false>
port: 50051
server_reflection_enabled: <true|false>
health_check_enabled: <true|false>
keep_alive:
max_connection_idle: 15
max_connection_age: 30
max_connection_age_grace: 5
time: 5
timeout: 1
log:
level: "<error|warn|info|debug>"

Here's the explanation for each option:

OptionDefaultDescription
grpc:
enabled: <true|false>
trueTurns the ability to communicate with the Proxy through gRPC on/off.
grpc:
port: 50051
50051The port used for gRPC communication.
grpc:
health_check_enabled: <true|false>
trueTurns the gRPC health check service on/off.
grpc:
server_reflection_enabled: <true|false>
falseTurns the gRPC server reflection on/off.
grpc:
keep_alive:
max_connection_idle: 15
INT_MAX (Infinite)Maximum time in seconds that a channel may have no outstanding rpcs, after which the server will close the connection. More about the gRPC keep-alive.
grpc:
keep_alive:
max_connection_age: 30
INT_MAX (Infinite)Maximum time in seconds that a channel may exist. More about the gRPC keep-alive.
grpc:
keep_alive:
max_connection_age_grace: 5
INT_MAX (Infinite)Grace period in seconds after the channel reaches its max age. More about the gRPC keep-alive.
grpc:
keep_alive:
time: 5
7200The interval in seconds between PING frames. More about the gRPC keep-alive.
grpc:
keep_alive:
timeout: 1
20The timeout in seconds for a PING frame to be acknowledged. If sender does not receive an acknowledgment within this time, it will close the connection. More about the gRPC keep-alive.
grpc:
log:
level: "<error|warn|info|debug>"
warnThe verbosity of the gRPC related logs.
Possible values: error, warn, info or debug.
When debug is set, the Proxy will log each RPC with additional details.