This is prerelease documentation for a service in preview release. It is subject to change.
Using the AWS SDK for Kotlin
After Setting up the SDK and Configuring the SDK, you are ready to make requests to AWS services such as Amazon S3, DynamoDB, IAM, Amazon EC2, and more.
This chapter provides instructions and programming examples you can use with the AWS SDK for Kotlin for specific features and AWS services.
Making requests
After you configure a service client, you instantiate it and use its methods to make requests to that AWS service.
For example, this code snippet shows how to create a RunInstancesRequest
object to create a new Amazon EC2 instance:
val ec2Client = Ec2Client.fromEnvironment() val runInstancesRequest = RunInstancesRequest { imageId = amiId instanceType = InstanceType.T1Micro maxCount = 1 minCount = 1 } ec2Client.runInstances(runInstancesRequest)
Each non-streaming operation on service clients has DSL overload, which is a type-safe way you can use to define the inputs for operations. For example, the following code snippet is equivalent to the previous one.
val ec2Client = Ec2Client.fromEnvironment() val runInstancesRequest = ec2Client.runInstances { imageId = amiId instanceType = InstanceType.T1Micro maxCount = 1 minCount = 1 }
If you have one or more operations to perform sequentially with the same AWS service, you can use the use
Ec2Client { region = "us-west-2" }.use { ec2Client -> ec2Client.runInstances { imageId = amiId instanceType = InstanceType.T1Micro maxCount = 1 minCount = 1 } }
Making concurrent requests
The AWS SDK for Kotlin is natively asynchronous. Each operation is
generated as a suspend
function, which you call from a coroutine. For
additional information about coroutines, refer to the official Kotlin
documentation
To make concurrent requests, use the asyncasync
returns a Deferredlaunch
returns a Job
import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import kotlin.system.measureTimeMillis import aws.sdk.kotlin.services.s3.S3Client fun main(): Unit = runBlocking { val s3 = S3Client { region = "us-west-2" } val myBucket = "
bucket-name
" val key1 = "first-object-key
" val key2 = "second-object-key
" val resp1 = async { s3.headObject { bucket = myBucket key = key1 } } val resp2 = async { s3.headObject { bucket = myBucket key = key2 } } val elapsed = measureTimeMillis { val totalContentSize = resp1.await().contentLength + resp2.await().contentLength println("Content length of $key1 + $key2 = $totalContentSize.") } println("Requests completed in $elapsed ms.") }
Making blocking requests
Since the SDK is natively asynchronous, you use the runBlocking
Streaming requests
To make requests containing binary data, you represent these as a
ByteStream
type. The SDK provides multiple convenience methods to supply
a ByteStream
, including the following:
-
ByteStream.fromFile(file: File)
-
File.asByteStream(): ByteStream
-
Path.asByteStream(): ByteStream
-
ByteStream.fromBytes(bytes: ByteArray)
-
ByteStream.fromString(str: String)
The following code snippet demonstrates basic usage of these methods.
val request = PutObjectRequest { ... body = ByteStream.fromFile(file) // body = ByteStream.fromBytes(byteArray) // body = ByteStream.fromString("string") // ... }
For more information and a complete list of methods available in the SDK, refer to
the aws.smithy.kotlin.runtime.content
package in the AWS
SDK for Kotlin API Reference.
Handling responses
When you make a request, you can use a response handler to process the response back from the AWS service.
For example, this code snippet shows an example of how to handle the response from
Amazon EC2 by printing out the instanceId
for the new instance from
the request above.
val response = ec2Client.runInstances(runInstancesRequest) println(response.instances?.get(0)?.instanceId)
Refer to the following code snippet for an example of how the complete request might
look with use
.
Ec2Client { region = "us-west-2" }.use { ec2Client -> val response = ec2Client.runInstances { imageId = amiId instanceType = InstanceType.T1Micro maxCount = 1 minCount = 1 } println(response.instances?.get(0)?.instanceId) }
Streaming responses
Binary data are represented as a ByteStream
type, an abstract read-only
stream of bytes.
Responses that contain binary stream data, such as from a getObject
request to Amazon S3, are handled with a lambda function instead of returning
the response directly. This scopes access to the response to the function, simplifying
lifetime management for both the caller and the SDK runtime. You must define what will
be returned from within the lambda, since all associated resources are released as soon
as the function returns.
val s3Client = S3Client.fromEnvironment() val req = GetObjectRequest { ... } val path = Paths.get("/tmp/download.txt") // GetObject has the following signature: // suspend fun <T> getObject(input: GetObjectRequest, block: suspend (GetObjectResponse) -> T): T val contentSize = s3Client.getObject(req) { resp -> // resp is valid until the end of the block // do not attempt to store or process the stream after the block returns // resp.body is of type ByteStream val rc = resp.body?.writeToFile(path) rc } println("SUCCESS: Wrote $contentSize bytes to $path")
The SDK provides various ways of consuming the ByteStream
type. These
include:
-
ByteStream.writeToFile(file: File): Long
-
ByteStream.writeToFile(path: Path): Long
-
ByteStream.toByteArray(): ByteArray
-
ByteStream.decodeToString(): String
For more information and a complete list, refer to the
aws.smithy.kotlin.runtime.content
package in the AWS
SDK for Kotlin API Reference.
Closing the client
When you no longer need the service client, close it.
ec2Client.close()
Service clients extend the Closable
interface. As a best practice -
especially with short-lived code such as AWS Lambda functions - explicitly
call the close()
method.