Type class for defining serialisation to and from
DynamoDB's AttributeValue
Type class for defining serialisation to and from
DynamoDB's AttributeValue
>>> val listOptionFormat = DynamoFormat[List[Option[Int]]] >>> listOptionFormat.read(listOptionFormat.write(List(Some(1), None, Some(3)))) Right(List(Some(1), None, Some(3)))
Also supports automatic derivation for case classes
>>> case class Farm(animals: List[String]) >>> case class Farmer(name: String, age: Long, farm: Farm) >>> val farmerF = DynamoFormat[Farmer] >>> farmerF.read(farmerF.write(Farmer("McDonald", 156L, Farm(List("sheep", "cow"))))) Right(Farmer(McDonald,156,Farm(List(sheep, cow))))
Problems reading a value are detailed
>>> case class Developer(name: String, age: String, problems: Int) >>> val invalid = DynamoFormat[Farmer].read(DynamoFormat[Developer].write(Developer("Alice", "none of your business", 99))) >>> invalid Left(InvalidPropertiesError(NonEmptyList(PropertyReadError(age,NoPropertyOfType(N,{S: none of your business,})), PropertyReadError(farm,MissingProperty)))) >>> invalid.leftMap(cats.Show[error.DynamoReadError].show) Left('age': not of type: 'N' was '{S: none of your business,}', 'farm': missing)
Optional properties are defaulted to None
>>> case class LargelyOptional(a: Option[String], b: Option[String]) >>> DynamoFormat[LargelyOptional].read(DynamoFormat[Map[String, String]].write(Map("b" -> "X"))) Right(LargelyOptional(None,Some(X)))
Custom formats can often be most easily defined using DynamoFormat.coercedXmap or DynamoFormat.xmap
Represents a DynamoDB table that operations can be performed against
Represents a DynamoDB table that operations can be performed against
>>> case class Transport(mode: String, line: String) >>> val transport = Table[Transport]("transport") >>> val client = LocalDynamoDB.client() >>> import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._ >>> LocalDynamoDB.withTable(client)("transport")('mode -> S, 'line -> S) { ... import com.gu.scanamo.syntax._ ... val operations = for { ... _ <- transport.putAll(Set( ... Transport("Underground", "Circle"), ... Transport("Underground", "Metropolitan"), ... Transport("Underground", "Central"))) ... results <- transport.query('mode -> "Underground" and ('line beginsWith "C")) ... } yield results.toList ... Scanamo.exec(client)(operations) ... } List(Right(Transport(Underground,Central)), Right(Transport(Underground,Circle)))
Provides a simplified interface for reading and writing case classes to DynamoDB
Provides a simplified interface for reading and writing case classes to DynamoDB
To avoid blocking, use com.gu.scanamo.ScanamoAsync
Provides the same interface as com.gu.scanamo.Scanamo, except that it requires an implicit concurrent.ExecutionContext and returns a concurrent.Future
Provides the same interface as com.gu.scanamo.Scanamo, except that it requires an implicit concurrent.ExecutionContext and returns a concurrent.Future
Note that that com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsyncClient just uses an java.util.concurrent.ExecutorService to make calls asynchronously