Using clients
Configuration
Section titled “Configuration”Supported protocols
Section titled “Supported protocols”Connect-Kotlin supports three protocols:
- The Connect protocol, a simple, HTTP-based protocol that works over HTTP/1.1 or HTTP/2. It takes the best parts of gRPC/gRPC-Web, including streaming, and packages them into a protocol that works well on all platforms, including mobile. Supports both JSON- and binary-encoded Protobuf.
- The gRPC protocol to talk to existing gRPC services.
- The gRPC-Web protocol to talk to existing gRPC-Web services.
If your backend services are already using gRPC today, Envoy provides support for converting requests made using the Connect and gRPC-Web protocols to gRPC.
Switching between these protocols is a one-line code change to
ProtocolClientConfig’s networkProtocol field:
val client = ProtocolClient( httpClient = ConnectOkHttpClient(OkHttpClient()), ProtocolClientConfig( host = host, serializationStrategy = GoogleJavaLiteProtobufStrategy(), networkProtocol = NetworkProtocol.CONNECT, // NetworkProtocol.GRPC or NetworkProtocol.GRPC_WEB. ),)Serialization strategies
Section titled “Serialization strategies”ProtocolClientConfig.serializationStrategy selects the message representation:
GoogleJavaLiteProtobufStrategy: Google Java lite types with Protobuf binary encoding. Smallest footprint; recommended for Android.GoogleJavaProtobufStrategy: Google Java types with Protobuf binary encoding. Larger but with the complete Java reflection API.GoogleJavaJSONStrategy: Google Java types with JSON encoding.
To switch strategies, change the strategy class and update the matching build settings:
| Variant | buf.gen.yaml opt | Protobuf runtime | Connect-Kotlin extension |
|---|---|---|---|
| Java lite | lite | protobuf-javalite + protobuf-kotlin-lite | connect-kotlin-google-javalite-ext |
| Java | (none) | protobuf-java + protobuf-kotlin | connect-kotlin-google-java-ext |
GoogleJavaProtobufStrategy and GoogleJavaJSONStrategy use the Java
variant. They differ only in wire format at runtime.
Compression
Section titled “Compression”Gzip is enabled by default. For other algorithms, write a CompressionPool
and register it; see GzipCompressionPool for reference.
HTTP stack
Section titled “HTTP stack”By default, HTTP networking uses OkHttp via the
ConnectOkHttpClient wrapper, which is just the OkHttp implementation of
HTTPClientInterface. Its constructor accepts an OkHttpClient for the
underlying network library. To swap in a different networking library,
provide your own HTTPClientInterface implementation.
Using generated clients
Section titled “Using generated clients”Coroutines
Section titled “Coroutines”Generated clients expose Kotlin suspend methods for unary RPCs:
val client = ProtocolClient( httpClient = ConnectOkHttpClient(OkHttpClient()), ProtocolClientConfig( host = "https://demo.connectrpc.com", serializationStrategy = GoogleJavaLiteProtobufStrategy(), networkProtocol = NetworkProtocol.CONNECT, ioCoroutineContext = Dispatchers.IO, // Dispatch RPC I/O on Dispatchers.IO. ),)val elizaServiceClient = ElizaServiceClient(client)lifecycleScope.launch { val response = elizaServiceClient.say(sayRequest { sentence = "Hello, Eliza" }) response.success { success -> println(success.message.sentence) } response.failure { error -> // Handle any errors from the request. }}For streaming RPCs, the client method returns a ServerOnlyStreamInterface
(for server-streaming) or BidirectionalStreamInterface (for bidi) that lets
you send messages and iterate over server responses using a ReceiveChannel:
val stream = elizaServiceClient.converse()lifecycleScope.launch { launch { for (response in stream.responseChannel()) { println(response.sentence) } } stream.send(converseRequest { sentence = "Hello, Eliza" }) stream.sendClose()}Callbacks
Section titled “Callbacks”If a callback-based approach is preferred, callbacks/closures can be used instead for unary methods. Streaming callback-based methods are not currently supported.
These methods are not generated by default, but are configurable using the
generateCallbackMethods option:
val cancelable = elizaServiceClient.say(sayRequest { sentence = "hello" }) { response -> response.success { result -> println(result.message.sentence) }}// cancelable() can be used to cancel the underlying request.