jpzk / bottledynamo

Good enough AWS DynamoDB abstraction in Scala with Circe JSON serialization using Twitter Futures

GitHub

bottledynamo

Build Status Codacy Badge codecov License GitHub stars

Bottle Dynamo is a good enough DynamoDB wrapper for putting and getting case classes in Scala. It uses Twitter's Futures and Circe as JSON serialization. Current features include:

  • In-Memory backend and DynamoDB
  • Support for exact-match get
  • Support for range queries (numbers as range key)

Dependency

Bottle Dynamo depends on Twitter Util Core (for futures), and on the AWS Java SDK DynamoDB (pullled in). Bottle Dynamo is available on Maven Central Repositories.

val bottledynamo = "com.madewithtea" %% "bottledynamo" % "1.0.0"

In-Memory (for tests)

import com.madewithtea.bottledynamo.{Store, Table, InMemoryKVImpl}
import io.circe.generic.auto._

case class SomeClass(field: String, number: Int)

val store = storeForKV(new InMemoryKVImpl)
val table = store.table[SomeClass]("sometable")

val entry = for { 
  _ <- table.create
  _ <- table.put("PK")(SomeClass("value",2)))
} yield table.get("PK")

Await.result(entry)

DynamoDB

import com.madewithtea.bottledynamo.{Store, Table, KV, DynamoDB, InMemoryKVImpl}
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB

val client = AmazonDynamoDBClientBuilder.standard()
      .withRegion(Regions.EU_CENTRAL_1)
      .build()

val store = storeForKV(new DynamoDB(client))
val table = store.table[SomeClass]("sometable")

val entry = for { 
  _ <- table.create
  _ <- table.put("PK")(SomeClass("value",2)))
} yield table.get("PK")

Await.result(entry)

DynamoDB and Range Tables

Create a table with DynamoDB interface first.

import com.madewithtea.bottledynamo.{Store, Table, KV, DynamoDB, InMemoryKVImpl}
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB

val client = AmazonDynamoDBClientBuilder.standard()
      .withRegion(Regions.EU_CENTRAL_1)
      .build()

val store = storeForKV(new DynamoDB(client))
val table = store.table[SomeClass]("sometable")

val entry = for { 
  _ <- table.put("PK", 10000)(SomeClass("value",2)))
} yield table.get("PK",10000)

Await.result(entry)

DynamoDB and Range Queries

Create a table with DynamoDB interface first

import com.madewithtea.bottledynamo.{Store, Table, KV, DynamoDB, InMemoryKVImpl}
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB

val client = AmazonDynamoDBClientBuilder.standard()
      .withRegion(Regions.EU_CENTRAL_1)
      .build()

val store = storeForKV(new DynamoDB(client))
val table = store.table[SomeClass]("sometable")

val entries = for { 
  _ <- table.put("PK", 10000)(SomeClass("value",2)))
  _ <- table.put("PK", 20000)(SomeClass("value",2)))
} yield table.query("PK",Some(0), Some(30000))

Await.result(entries)