Last active
February 3, 2026 20:18
-
-
Save dacr/a8106dd83c6b1c9f08afcbc96be0aae3 to your computer and use it in GitHub Desktop.
ZIO learning - an enhanced authentication service with http service used multiple times / published by https://github.com/dacr/code-examples-manager #4917e032-083a-4844-8104-3044fcb53f3e/3bc6f193ec7ef8e5d1a52073e811c8ac3a731355
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 - an enhanced authentication service with http service used multiple times | |
| // keywords : scala, zio, learning, authentication, pure-functional, @testable | |
| // publish : gist | |
| // authors : David Crosson | |
| // license : Apache License Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0.txt) | |
| // id : 4917e032-083a-4844-8104-3044fcb53f3e | |
| // created-on : 2022-01-16T19:12:41+01:00 | |
| // managed-by : https://github.com/dacr/code-examples-manager | |
| // run-with : scala-cli $file | |
| // --------------------- | |
| //> using scala "3.4.2" | |
| //> using dep "dev.zio::zio:2.0.13" | |
| //> using dep "fr.janalyse::zio-worksheet:2.0.13.0" | |
| // --------------------- | |
| import zio.*, zio.worksheet.* | |
| // ------------------------------------------------------------- | |
| trait HttpService: | |
| def httpGet(query: String): Task[String] | |
| case class HttpServiceLive() extends HttpService: | |
| override def httpGet(query: String): Task[String] = | |
| for | |
| httpProxy <- System.env("http_proxy") | |
| body <- ZIO.succeed("secured-auth-token") | |
| yield body | |
| object HttpService: | |
| val live = ZLayer.succeed(HttpServiceLive()) | |
| def httpGet(query: String): RIO[HttpService, String] = ZIO.serviceWithZIO(_.httpGet(query)) | |
| // ------------------------------------------------------------- | |
| case class AuthToken(token: String) | |
| trait Authenticator: | |
| def authenticate: Task[AuthToken] | |
| case class AuthenticatorLive(httpService: HttpService) extends Authenticator: | |
| override def authenticate: Task[AuthToken] = | |
| for | |
| username <- System.env("APP_USERNAME") | |
| password <- System.env("APP_PASSWORD") | |
| body <- httpService.httpGet("http://127.0.0.1/auth") | |
| token = "secured-auth-token" | |
| yield AuthToken(token) | |
| object Authenticator: | |
| val live = ZLayer( | |
| for httpService <- ZIO.service[HttpService] | |
| yield AuthenticatorLive(httpService) | |
| ) | |
| def authenticate: RIO[Authenticator, AuthToken] = ZIO.serviceWithZIO(_.authenticate) | |
| // ------------------------------------------------------------- | |
| val app: ZIO[HttpService & Authenticator, Throwable, Unit] = | |
| for | |
| _ <- Console.printLine("started") | |
| token <- Authenticator.authenticate | |
| _ <- Console.printLine(s"got token $token") | |
| yield () | |
| // ------------------------------------------------------------- | |
| // -- Better to write : | |
| val layers = ZLayer.make[HttpService & Authenticator]( | |
| HttpService.live, | |
| Authenticator.live | |
| ) | |
| // -- Rather than that which requires to resolve by yourself the dependencies graph | |
| val layersAlt = HttpService.live >>> Authenticator.live ++ HttpService.live | |
| // ------------------------------------------------------------- | |
| // -- And even better we can use provide in order to let ZIO build the dependency graph for us :) | |
| app.provide(HttpService.live, Authenticator.live).unsafeRun |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment