This project is a service generator plugin for PBandK that generates Kotlin client integration for Twirp services. The generated client code leverages PBandK for protobuf messages, kotlinx.serialization for JSON handling of Twirp service errors, and Ktor for HTTP. All of these choices enable the generated client code to be leveraged in Kotlin Multiplatform Mobile projects, sharing the network integration layer with both iOS and Android native apps.
There are two parts to this project - the generator itself, and the supporting runtime for leveraging the generated service code.
In general, follow PBandK Usage instructions, but supply the twirp-kmm-generator
as the kotlin_service_gen
option as described in PBandK's Service Code Generation documentation.
Download the latest release, currently 0.4.0
, and pass it to protoc
via pbandk
:
# Download the library to ~
cd ~/
curl -OL https://github.com/collectiveidea/twirp-kmm/releases/download/0.4.0/twirp-kmm-generator-0.4.0.jar
Pass the jar and generator class name as the kotlin_service_gen
option to pbandk_out
:
cd ~/exampleProject
protoc --pbandk_out=kotlin_service_gen='~/twirp-kmm-generator-0.4.0.jar|com.collectiveidea.twirp.Generator',kotlin_package=com.example.api:src/main/kotlin src/main/proto/example.proto
To build the library locally, run:
./gradlew build
This creates the versioned .jar
file, e.g. generator/build/libs/twirp-kmm-generator-0.4.0-SNAPSHOT.jar
Then, the built version can be used, instead of the latest release, by supplying the path to the built .jar
, e.g.:
protoc --pbandk_out=kotlin_service_gen='/Users/darron/Development/twirp-kmm/generator/build/libs/twirp-kmm-generator-0.4.0-SNAPSHOT.jar|com.collectiveidea.twirp.Generator',kotlin_package=com.example.api:shared/src/commonMain/kotlin shared/src/commonMain/proto/example.proto
The runtime provides an installTwirp
helper to configure a Ktor HttpClient for Twirp integration.
First, add the runtime as a dependency:
implementation "com.collectiveidea.twirp:twirp-kmm-runtime:0.4.0"
Then, configure the HttpClient and pass the client into the generated service constructor:
val client = HttpClient(engine) {
installTwirp(baseUrl)
}
val exampleService = ExampleServiceImpl(client)
Service methods throw a ServiceException
on error. The ServiceException
contains the parsed error response from the Twirp service JSON body.