Last active
May 25, 2024 10:20
-
-
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/9ae119c6e9fb12ff7f9ac8207f4d822907612d66
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 NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2) | |
// 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