Generating Clients¶
The Smithy Kotlin build plugin, kotlin-codegen, generates Kotlin clients from Smithy models,
and can be executed with Gradle (recommended) or the Smithy CLI.
Important
The Smithy CLI is a prerequisite for this guide. See the Smithy CLI installation guide if you do not already have the CLI installed.
Initial setup: Gradle (recommended)¶
To generate a Kotlin client for a service, start by creating a new Smithy Gradle project.
The smithy init CLI command can be used to create a new Smithy Gradle project:
smithy init -t quickstart-gradle
A Smithy Gradle project should contain a Gradle settings file, a Gradle build script, a smithy-build.json configuration file, and a model/ directory containing Smithy models. For example:
my-project/
├── model/
│ ├── ...
├── smithy-build.json
├── build.gradle.kts
└── settings.gradle.kts
To your Gradle build script, apply the the Kotlin JVM plugin, and the smithy-base plugin (for building your Smithy model):
plugins {
+ kotlin("jvm") version "2.3.0"
+ id("software.amazon.smithy.gradle.smithy-base") version "1.3.0"
}
Add the following dependencies to your project:
dependencies {
// Code generator
compileOnly(libs.smithy.kotlin.codegen)
// Client Dependencies
implementation(libs.smithy.kotlin.runtime.core)
implementation(libs.smithy.kotlin.smithy.client)
implementation(libs.smithy.kotlin.http.client)
implementation(libs.smithy.kotlin.telemetry.api)
implementation(libs.smithy.kotlin.telemetry.defaults)
implementation(libs.smithy.kotlin.rpcv2.protocol)
implementation(libs.smithy.kotlin.aws.protocol.core)
implementation(libs.smithy.kotlin.aws.signing.common)
implementation(libs.smithy.kotlin.serde)
implementation(libs.smithy.kotlin.serde.cbor)
implementation(libs.smithy.kotlin.http.client.engine.default)
implementation(libs.kotlinx.coroutines.core)
}
Add a version catalog to manage your dependencies and their versions:
smithy-kotlin-version="1.6.0"
coroutines-core-version="1.10.2"
smithy-kotlin-codegen = { module = "aws.smithy.kotlin:codegen", version.ref = "smithy-kotlin-version" }
smithy-kotlin-runtime-core = { module = "aws.smithy.kotlin:runtime-core", version.ref = "smithy-kotlin-version" }
smithy-kotlin-smithy-client = { module = "aws.smithy.kotlin:smithy-client", version.ref = "smithy-kotlin-version" }
smithy-kotlin-http-client = { module = "aws.smithy.kotlin:http-client", version.ref = "smithy-kotlin-version" }
smithy-kotlin-telemetry-api = { module = "aws.smithy.kotlin:telemetry-api", version.ref = "smithy-kotlin-version" }
smithy-kotlin-telemetry-defaults = { module = "aws.smithy.kotlin:telemetry-defaults", version.ref = "smithy-kotlin-version" }
smithy-kotlin-rpcv2-protocol = { module = "aws.smithy.kotlin:smithy-rpcv2-protocols", version.ref = "smithy-kotlin-version" }
smithy-kotlin-aws-protocol-core = { module = "aws.smithy.kotlin:aws-protocol-core", version.ref = "smithy-kotlin-version" }
smithy-kotlin-aws-signing-common = { module = "aws.smithy.kotlin:aws-signing-common", version.ref = "smithy-kotlin-version" }
smithy-kotlin-serde = { module = "aws.smithy.kotlin:serde", version.ref = "smithy-kotlin-version" }
smithy-kotlin-serde-cbor = { module = "aws.smithy.kotlin:serde-cbor", version.ref = "smithy-kotlin-version" }
smithy-kotlin-http-client-engine-default = { module = "aws.smithy.kotlin:http-client-engine-default", version.ref = "smithy-kotlin-version" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines-core-version" }
Now, define a service model in a model/ directory at the root of your project.
The smithy-base Gradle plugin will automatically discover any models added to that directory.
Configuring code generation¶
In order to execute code generation, the kotlin-codegen plugin must be added to
your smithy-build config:
{
"version": "1.0",
"plugins": {
+ "kotlin-codegen": {
+ "service": "com.example#CoffeeShop", // Replace with your service's ID
+ "sdkId": "CoffeeShop", // Replace with your service's SDK ID
+ "package": {
+ "name": "io.smithy.kotlin.client.example", // Generated Kotlin code will use this as the root package namespace
+ "version": "0.0.1"
+ }
+ }
}
}
Add Smithy build to the Kotlin build¶
To ensure your client code is generated on every Kotlin build, Gradle must be configured to run a Smithy build before Kotlin compilation in your Gradle build script:
tasks.named("compileKotlin") {
dependsOn("smithyBuild")
}
Add generated code to the Kotlin sourceSet¶
Your package is now configured to generate Kotlin client source code. However, the generated code must be added to a source set to be compiled. To add the generated code to the main source set, add the following to your Gradle build script:
afterEvaluate {
val clientPath = smithy.getPluginProjectionPath(smithy.sourceProjection.get(), "kotlin-codegen")
sourceSets.main.get().kotlin.srcDir(clientPath)
}
Opt in to internal APIs¶
Some of the code generated client APIs are public but marked with an InternalApi
annotation to discourage client end users from using them outside of generated code.
To opt in to the InternalApi annotation, add the following to your Gradle build script:
val optinAnnotations = listOf("kotlin.RequiresOptIn", "aws.smithy.kotlin.runtime.InternalApi")
kotlin.sourceSets.all {
optinAnnotations.forEach { languageSettings.optIn(it) }
}
Generating code¶
To generate and compile your client code, run a build from the root of your Gradle project:
./gradlew clean build
Building the project will generate code in the
build/smithy-projections/<project-name>/source/kotlin-codegen/ directory.