1

I need to put my data classes into DynamoDb. How can I make it with annotations?

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute
import kotlinx.serialization.Serializable

@Serializable
data class Item(
    @DynamoDBAttribute var name: String = "",
    @DynamoDBAttribute var id: String = "",
    @DynamoDBAttribute var stuff: String = ""
    ...
)

suspend fun putItemInTable() {
        val request = PutItemRequest {
            tableName = "table"
            item = Item() // How to send it properly?
        }

        DynamoDbClient { region = AWS_REGION }.use { ddb ->
            ddb.putItem(request)
            println("A new item was placed into.")
        }
}

I suppose, it should be not much harder Android + Room converters out of the box, right?

build.gradle.kts:

implementation ("aws.sdk.kotlin:dynamodb:$awsVersion")
implementation ("com.amazonaws:aws-java-sdk-dynamodb:1.12.477")

Current AWS documentation is unorganized, how can I get Kotlin version of aws-java-sdk-dynamodb?

smac2020
  • 9,637
  • 4
  • 24
  • 38
Psijic
  • 743
  • 7
  • 20
  • What document are you looking at to get that code example. Its not in the Kotlin AWS Docs. – smac2020 May 31 '23 at 14:29
  • Tried to combine those: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Annotations.html https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb-items.html But found Gradle dependencies only somewhere outside. – Psijic May 31 '23 at 14:44
  • As i specified in my answer - look at the Developer Doc for Kotlin and use the SDK for full benefits of Kotlin. DO not use Java V1 with Kotlin. – smac2020 May 31 '23 at 14:45
  • Also - find a functioning Gradle build file here - https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/dynamodb – smac2020 May 31 '23 at 14:47
  • I did see that file, no mapping there. Looks like it is a long way to add it to Kotlin especially if all aws.sdk.kotlin versions in beta. – Psijic May 31 '23 at 14:52
  • If you need to use Mapping over Kotlin and Coroutine functionality -- still move away from Java V1 and move to the AWS SDK for Java V2 and the Enhanced Client. Still a better choice then V1. See -- https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html – smac2020 May 31 '23 at 14:55
  • Thanks. Maybe using Kotlin version is still better as for now, especially with Android. But if this V2 supports both mapping and coroutines - not sure why it's not implemented in Kotlin version. – Psijic May 31 '23 at 15:03
  • I think the SDK team is aware. It still a new SDK - but far better then Java V1. That SDK is not recommended to use any more. If you want to use Java - move to AWS SDK for Java V2, – smac2020 May 31 '23 at 15:07
  • See my update about Android – smac2020 May 31 '23 at 15:08

1 Answers1

1

Although you are using this data type that uses v2:

com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute

This is actually AWS SDK for Java V1. To use Kotlin and DynamoDB, you should consider using the AWS SDK for Kotlin, not AWS SDK for Java V1.

The Developer Guide for AWS SDK for Kotlin is here:

What is the AWS SDK for Kotlin?

The AWS SDK for Kotlin supports language features like coroutines that you will not get with Java V1. See:

Coroutines

You can use the AWS SDK for Kotlin to interact with Amazon DynamoDB. There are many examples. I suggest you look in the AWS Code Library under the Kotlin SDK and DynamoDB section:

DynamoDB examples using SDK for Kotlin

You will find many code examples including how to use this SDK - including this multi operation scenario:

Get started with tables, items, and queries

If you prefer - look at AWS Github for DynamoDB:

https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/dynamodb

In Github, you will find how to add an item using the AWS SDK for Kotlin. Notice the use of mutableMapOf to add an item.

  package com.kotlin.dynamodb

  // snippet-start:[dynamodb.kotlin.put_item.import]
  import aws.sdk.kotlin.services.dynamodb.DynamoDbClient
  import aws.sdk.kotlin.services.dynamodb.model.AttributeValue
  import aws.sdk.kotlin.services.dynamodb.model.PutItemRequest
  import kotlin.system.exitProcess
  // snippet-end:[dynamodb.kotlin.put_item.import]

  /**
  Before running this Kotlin code example, set up your development 
  environment, including your credentials.

  For more information, see the following documentation topic:
  https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer- 
  guide/setup.html
  */

 suspend fun main(args: Array<String>) {
    val usage = """
        Usage:
            <tableName> <key> <keyVal> <albumtitle> <albumtitleval> <awards> <awardsval> <Songtitle> <songtitleval>

        Where:
            tableName - The Amazon DynamoDB table in which an item is placed (for example, Music3).
            key - The key used in the Amazon DynamoDB table (for example, Artist).
            keyval - The key value that represents the item to get (for example, Famous Band).
            albumTitle - The album title (for example, AlbumTitle).
            AlbumTitleValue - The name of the album (for example, Songs About Life).
            Awards - The awards column (for example, Awards).
            AwardVal - The value of the awards (for example, 10).
            SongTitle - The song title (for example, SongTitle).
            SongTitleVal - The value of the song title (for example, Happy Day).
            """"

    if (args.size != 9) {
        println(usage)
        exitProcess(0)
    }

    val tableName = args[0]
    val key = args[1]
    val keyVal = args[2]
    val albumTitle = args[3]
    val albumTitleValue = args[4]
    val awards = args[5]
    val awardVal = args[6]
    val songTitle = args[7]
    val songTitleVal = args[8]

    putItemInTable(tableName, key, keyVal, albumTitle, albumTitleValue, awards, awardVal, songTitle, songTitleVal)
}

  // snippet-start:[dynamodb.kotlin.put_item.main]
  suspend fun putItemInTable(
    tableNameVal: String,
    key: String,
    keyVal: String,
    albumTitle: String,
    albumTitleValue: String,
    awards: String,
    awardVal: String,
    songTitle: String,
    songTitleVal: String
   ) {
   
    val itemValues = mutableMapOf<String, AttributeValue>()

    // Add all content to the table.
    itemValues[key] = AttributeValue.S(keyVal)
    itemValues[songTitle] = AttributeValue.S(songTitleVal)
    itemValues[albumTitle] = AttributeValue.S(albumTitleValue)
    itemValues[awards] = AttributeValue.S(awardVal)

    val request = PutItemRequest {
        tableName = tableNameVal
        item = itemValues
    }

    DynamoDbClient { region = "us-east-1" }.use { ddb ->
        ddb.putItem(request)
        println(" A new item was placed into $tableNameVal.")
    }
   }
  // snippet-end:[dynamodb.kotlin.put_item.main]

ANDROID

I noticed in your comments you mentioned Android. Find this Android/AWS SDK for Kotlin tutorial. It will help you get up and running with the AWS SDK for Kotlin in an Android Studio project.

https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/usecases/first_android_app

smac2020
  • 9,637
  • 4
  • 24
  • 38
  • I found the stuff about coroutines and no mapping there https://stackoverflow.com/questions/70212036/modelling-complex-types-for-dynamodb-in-kotlin Looks like it was your answer. Hope something changed with mapping after 1.5 years passed. – Psijic May 31 '23 at 14:49
  • The AWS SDK for Kotlin for DynamoDB does not yet support data mapping. You need to use a Kotlin collection (ie -- mutableMapOf) that i showed in my code example to add an item. – smac2020 May 31 '23 at 14:51
  • Yeah, it's sad especially if Kotlin can't make a loop through its parameters. – Psijic May 31 '23 at 14:57
  • Although the SDK is new , you should decide if you prefer full support of language features such as corountines that you do not get with Java SDK vs using collections to add items. – smac2020 May 31 '23 at 15:00
  • Looks like coroutines is something better for performance. – Psijic May 31 '23 at 15:08
  • That is a correct assumption – smac2020 May 31 '23 at 15:10