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))