How do you connect your business services with zio-http (ZIO 2.x) routes?

430 views Asked by At

I can't manage to connect zio-http with my backend services, defined as ZLayers. The examples I found just show how to expose HTTP endpoints such as:

import zio._
import zhttp.http._
import zhttp.service.Server

object HelloWorld extends App {
  val app = Http.collect[Request] {
    case Method.GET -> !! / "text" => Response.text("Hello World!")
  }

  override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] =
    Server.start(8090, app).exitCode
}

Now, assuming I the following ZIO Service with its corresponding ZLayer in the companion object:

  case class GetDepartmentUseCaseImpl(getDepartmentByCodeDrivenPort: GetDepartmentByCodeDrivenPort) extends GetDepartmentUseCase {
    override def execute(param: String): ZIO[Any, Throwable, Option[Department]] = {
      for {
        dep: Option[Department] <- getDepartmentByCodeDrivenPort.get(param)
      } yield dep
    }
  }
  object GetDepartmentUseCaseImpl {
    val layer = ZLayer.fromFunction(GetDepartmentUseCaseImpl.apply _)
  }

How do you expose an endpoint /departments/{id} that calls the previous service and returns 200 + json for Some(Department) and 404 for Nothing?

Versions used:

val zioVersion = "2.0.0-RC5"
val zioHttpVersion = "2.0.0-RC7"
1

There are 1 answers

0
Shruti Verma On

You can try this:

  1. In your companion object, create a def which returns a ZIO of response
 object GetDepartmentUseCaseImpl  {
   val layer: ZLayer[Any, Nothing, Has[GetDepartmentUseCaseImpl]] = ???
 
   def get: ZIO[Has[GetDepartmentUseCaseImpl], Throwable, Response] = ???
 }
  1. Create your app like this:
// Create HTTP route
 val app: Http[Has[GetDepartmentUseCaseImpl], Throwable, Request, Response] = Http.collectZIO[Request] {
   case Method.GET -> !! / "departments" / _ =>
     GetDepartmentUseCaseImpl.get
 }
  1. Provide layer while bootstrapping server:
// Run it like any simple app
 override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] =
   Server
     .start(8090, app)
     .provideCustomLayer(GetDepartmentUseCaseImpl.layer)
     .exitCode