Last active
February 3, 2026 20:26
-
-
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/212a46c79d773e82f9a2beaaa089868f3ff8d7b3
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 License Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0.txt) | |
| // 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