Skip to content

Commit

Permalink
feat(server): Use zServerLogic and implement services package (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevchuang authored Feb 25, 2024
1 parent a1b3a93 commit 82fbfee
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package io.kevchuang.reviewboard

import io.kevchuang.reviewboard.http.endpoints.HealthEndpoint
import io.kevchuang.reviewboard.http.routes.*
import io.kevchuang.reviewboard.http.server.{HttpServer, HttpServerLive}
import io.kevchuang.reviewboard.services.Services
import io.kevchuang.reviewboard.services.health.*
import zio.*
import zio.http.Server

object Application extends ZIOAppDefault:

private val program: ZIO[HttpServer & Server, Throwable, Unit] =
private val program: ZIO[HttpServer & Server & Services, Throwable, Unit] =
for
healthRoutes <- HealthRoutes.make
routes = healthRoutes.routes
Expand All @@ -17,6 +17,6 @@ object Application extends ZIOAppDefault:

override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] =
program
.provide(Server.default, HttpServerLive.live)
.provide(Server.default, HttpServerLive.live, HealthServiceLive.live)

end Application

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package io.kevchuang.reviewboard.http.endpoints

import io.kevchuang.reviewboard.domain.health.*
import io.kevchuang.reviewboard.domain.health.HealthCheckResponse.given
import io.kevchuang.reviewboard.http.controllers.HealthController
import io.kevchuang.reviewboard.services.health.HealthService
import sttp.tapir.*
import sttp.tapir.codec.iron.{*, given}
import sttp.tapir.generic.auto.*
import sttp.tapir.json.zio.{*, given}
import zio.{Task, UIO}
import zio.*

final case class HealthEndpoint(healthController: HealthController)
extends HttpEndpoint[Unit, Unit, HealthCheckResponse]:
final case class HealthEndpoint(health: HealthService)
extends HttpEndpoint[HealthService, Unit, Unit, HealthCheckResponse]:
def endpointDescription: ApiEndpoint[Unit, Unit, HealthCheckResponse] =
endpoint
.tag("health")
Expand All @@ -20,13 +20,12 @@ final case class HealthEndpoint(healthController: HealthController)
.in("health")
.out(jsonBody[HealthCheckResponse])

def endpointLogic: Unit => Task[HealthCheckResponse] = _ =>
healthController.allGood
def endpointLogic: Unit => UIO[HealthCheckResponse] = _ => health.checkHealth
end HealthEndpoint

object HealthEndpoint:
def make: UIO[HealthEndpoint] =
for healthController <- HealthController.make
yield HealthEndpoint(healthController)
def make: RIO[HealthService, HealthEndpoint] =
for health <- ZIO.service[HealthService]
yield HealthEndpoint(health)

end HealthEndpoint
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.kevchuang.reviewboard.http.endpoints

import sttp.tapir.server.ServerEndpoint
import sttp.tapir.ztapir.*
import zio.*

trait HttpEndpoint[I, E, O]:
trait HttpEndpoint[R, I, E, O]:
def endpointDescription: ApiEndpoint[I, E, O]
def endpointLogic: I => Task[O]
def serverEndpoint: ServerEndpoint[Any, Task] =
endpointDescription.serverLogicSuccess[Task](endpointLogic)
def endpointLogic: I => ZIO[R, E, O]
def serverEndpoint: ZServerEndpoint[R, Any] =
endpointDescription.zServerLogic(endpointLogic)
end HttpEndpoint
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package io.kevchuang.reviewboard.http.routes

import io.kevchuang.reviewboard.http.endpoints.HealthEndpoint
import io.kevchuang.reviewboard.services.health.HealthService
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.ztapir.*
import zio.*

private case class HealthRoutes(healthEndpoint: HealthEndpoint)
extends HttpRoute:
def routes: List[ServerEndpoint[Any, Task]] =
extends HttpRoute[HealthService]:
def endpoints: List[ZServerEndpoint[HealthService, Any]] =
List(healthEndpoint.serverEndpoint)
end HealthRoutes

object HealthRoutes:
def make: UIO[HealthRoutes] =
def make: RIO[HealthService, HealthRoutes] =
for healthEndpoint <- HealthEndpoint.make
yield HealthRoutes(healthEndpoint)
end HealthRoutes
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package io.kevchuang.reviewboard.http.routes

import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.ziohttp.{ZioHttpInterpreter, ZioHttpServerOptions}
import sttp.tapir.ztapir.ZServerEndpoint
import zio.*
import zio.http.HttpApp

trait HttpRoute:
def routes: List[ServerEndpoint[Any, Task]]
trait HttpRoute[R]:
def endpoints: List[ZServerEndpoint[R, Any]]
def routes: HttpApp[R] = ZioHttpInterpreter().toHttp(endpoints)
end HttpRoute
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package io.kevchuang.reviewboard.http.server

import sttp.tapir.server.ServerEndpoint
import zio.*
import zio.http.Server
import zio.http.{HttpApp, Server}

trait HttpServer:
def start(
routes: List[ServerEndpoint[Any, Task]]
): ZIO[Server, Throwable, Unit]
def start[R](
routes: HttpApp[R]
): ZIO[R & Server, Throwable, Unit]
end HttpServer

object HttpServer:
def start(
routes: List[ServerEndpoint[Any, Task]]
): ZIO[HttpServer & Server, Throwable, Unit] =
def start[R](
routes: HttpApp[R]
): ZIO[R & HttpServer & Server, Throwable, Unit] =
ZIO.serviceWithZIO[HttpServer](_.start(routes))
end HttpServer
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
package io.kevchuang.reviewboard.http.server

import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.ziohttp.{ZioHttpInterpreter, ZioHttpServerOptions}
import zio.*
import zio.http.Server
import zio.http.{HttpApp, Server}

object HttpServerLive:
def live: ZLayer[Any, Nothing, HttpServer] =
lazy val live: ZLayer[Any, Nothing, HttpServer] =
ZLayer.succeed(
new HttpServer:
override def start(
endpoints: List[ServerEndpoint[Any, Task]]
): ZIO[Server, Throwable, Unit] =
Server
.serve(
ZioHttpInterpreter(
ZioHttpServerOptions.default
).toHttp(endpoints)
)
override def start[R](
routes: HttpApp[R]
): ZIO[R & Server, Throwable, Unit] = Server.serve(routes)
)
end HttpServerLive
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.kevchuang.reviewboard.services.health

import io.kevchuang.reviewboard.domain.health.HealthCheckResponse
import zio.*

trait HealthService:
def checkHealth: ZIO[Any, Nothing, HealthCheckResponse]
end HealthService

object HealthService:
def checkHealth: ZIO[HealthService, Nothing, HealthCheckResponse] =
ZIO.serviceWithZIO[HealthService](_.checkHealth)
end HealthService
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.kevchuang.reviewboard.services.health

import io.kevchuang.reviewboard.domain.health.HealthCheckResponse
import zio.*
import io.github.iltotore.iron.*

object HealthServiceLive:
lazy val live: ULayer[HealthService] =
ZLayer.succeed(
new HealthService:
def checkHealth: UIO[HealthCheckResponse] =
ZIO.succeed(HealthCheckResponse("All good !"))
)
end HealthServiceLive
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.kevchuang.reviewboard

import io.kevchuang.reviewboard.services.health.HealthService

package object services:
type Services = HealthService
end services

0 comments on commit 82fbfee

Please sign in to comment.