Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/29c763f82e443bd3e9848af2e2ea5582 to your computer and use it in GitHub Desktop.
Save dacr/29c763f82e443bd3e9848af2e2ea5582 to your computer and use it in GitHub Desktop.
ZIO learning - structured services - horizontal composition / published by https://github.com/dacr/code-examples-manager #e3518fe7-c997-4684-8eff-6074a7056521/c02df7ad84983afa7449db6fb03632e162a322f8
// summary : ZIO learning - structured services - horizontal composition
// keywords : scala, zio, learning, services, pure-functional, @testable
// publish : gist
// authors : Rock the JVM
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : e3518fe7-c997-4684-8eff-6074a7056521
// created-on : 2021-05-03T18:04:46+02:00
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// Highly inspired from Structuring Services in Scala with ZIO and ZLayer : https://www.youtube.com/watch?v=PaogLRrYo64
// And lately updated or Scala3 & ZIO2
// ---------------------
//> using scala "3.2.2"
//> using dep "dev.zio::zio:2.0.13"
// ---------------------
import zio.*
// ----------------------------------------------------------------------------------------
case class User(name: String, email: String)
// ----------------------------------------------------------------------------------------
// This is the classical service pattern used within ZIO, with the standard naming scheme
// Service definition
trait UserEmailer:
def notify(user: User, message: String): Task[Unit]
object UserEmailer:
class UserEmailerImpl() extends UserEmailer:
override def notify(user: User, message: String): Task[Unit] =
ZIO.attempt(println(s"[User emailer] Sending '$message' to ${user.email}'"))
val live: URLayer[Any, UserEmailer] = ZLayer.succeed(UserEmailerImpl())
// Front-facing API - helper function
def notify(user: User, message: String): RIO[UserEmailer, Unit] =
ZIO.serviceWithZIO(_.notify(user, message))
// ----------------------------------------------------------------------------------------
trait UserDb:
def insert(user: User): Task[Unit]
object UserDb:
class UserDbImpl extends UserDb:
override def insert(user: User) =
ZIO.attempt(println(s"[Database] insert into public.user value ('${user.email}')"))
val live = ZLayer.succeed(UserDbImpl())
def insert(user: User): RIO[UserDb, Unit] = {
ZIO.serviceWithZIO(_.insert(user))
}
// ----------------------------------------------------------------------------------------
object Encapsulated extends ZIOAppDefault:
val david = User("david", "myemail@gmail.com")
val message = "Welcome to this site !"
val layers = ZLayer.make[UserDb & UserEmailer](
UserDb.live,
UserEmailer.live
)
val logic =
UserEmailer
.notify(david, message) // the kind of effect
.provideLayer(layers) // provide the input for that effect
override def run = logic
Encapsulated.main(Array.empty)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment