Skip to main content
Version: 2.x

Getting Started with ZIO Bson

ZIO Bson is BSON library with tight ZIO integration.

Development CI Badge Sonatype Releases Sonatype Snapshots javadoc ZIO Bson

Introduction​

The goal of this project is to create the best all-round BSON library for Scala:

  • Native BSON support to avoid intermediate JSON conversions and support BSON types.
  • Future-Proof, prepared for Scala 3 and next-generation Java.
  • Simple small codebase, concise documentation that covers everything.
  • Helpful errors are readable by humans and machines.
  • ZIO Integration so nothing more is required.

Installation​

In order to use this library, we need to add the following lines in our build.sbt file:

libraryDependencies += "dev.zio" %% "zio-bson" % "1.0.7"
libraryDependencies += "dev.zio" %% "zio-bson-magnolia" % "1.0.7"

zio-schema support​

zio-bson-magnolia projects provides typeclass derivation only for scala 2.13. You can use zio-schema-bson instead to get typeclass derivation on scala 2.12, 2.13 and 3.

Example​

All the following code snippets assume that the following imports have been declared

import zio.bson._
import zio.bson.BsonBuilder._

Declaring codecs​

Use DeriveBsonCodec.derive to get a codec for your case class or sealed trait:

import zio.bson.magnolia._

case class Banana(curvature: Double)

object Banana {
implicit val codec: BsonCodec[Banana] = DeriveBsonCodec.derive
}

Converting to BsonValue​

To use values in Filter of Update expressions you can convert them to BsonValue this way:

"str".toBsonValue

Banana(0.2).toBsonValue

import org.bson._

def method[T: BsonEncoder](value: T): BsonDocument = doc("key" -> value.toBsonValue)

Creating CodecProvider​

To get CodecProvider for your BsonCodec use zioBsonCodecProvider:

val codecProvider = zioBsonCodecProvider[Banana]

Parsing BsonValue​

In general CodecProvider should parse your case class without intermediate BsonValue representation. But you can parse BsonValue any way:

import BsonBuilder._

val bsonVal: BsonValue = doc("curvature" -> double(0.2))

bsonVal.as[Banana]

Errors​

Bad BSON will produce an error with path and contextual information

scala> doc("curvature" -> Array[Byte](1, 2, 3).toBsonValue).as[Banana]
val res: Either[String,Banana] = Left(.curvature: Expected BSON type Double, but got BINARY.)

Configuration​

You can configure typeclass derivation with annotations.

import zio.bson._
import zio.bson.BsonBuilder._
import zio.bson.magnolia._

sealed trait Fruit

object Fruit {
case class Banana(curvature: Double) extends Fruit
case class Apple(poison: Boolean) extends Fruit

implicit val codec: BsonCodec[Fruit] = DeriveBsonCodec.derive
}

val bsonFruit = doc( "Banana" -> doc( "curvature" -> double(0.5) ))

bsonFruit.as[Fruit]
//Right(Banana(0.5))

@bsonDiscriminator("$type")
sealed trait FruitConfigured

object FruitConfigured {
case class Banana(curvature: Double) extends FruitConfigured
@bsonHint("custom_type_name")
case class Apple(@bsonField("is_poisoned") poison: Boolean) extends FruitConfigured

implicit val codec: BsonCodec[FruitConfigured] = DeriveBsonCodec.derive
}

val bsonFruitConfigured = doc(
"$type" -> str("custom_type_name"),
"is_poisoned" -> bool(true)
)

bsonFruitConfigured.as[FruitConfigured]
//Right(Apple(true))