Last active
May 6, 2023 15:39
-
-
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
This file contains 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.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