Last active
May 25, 2024 10:19
-
-
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/a6124b52ebdc01fbeea5174890cc227190281ebe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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.4.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", "[email protected]") | |
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