What is the difference between ZLayer.scoped and ZLayer.fromZio?

134 views Asked by At

I am confused by many different ways in ZIO to do what seems to be the same thing (at least to my noobie eye).

In particular, something like this:

val layer: RLayer[ServiceA with ServiceB, ServiceC] = ZLayer.scoped {
  for {
     a <- ZIO.service[ServiceA]
     b <- ZIO.service[ServiceB]
  } yield new ServiceCImpl(a, b)
}

vs

val layer2: RLayer[ServiceA with ServiceB, ServiceC] = ZLayer.fromZIO {
  for {
     a <- ZIO.service[ServiceA]
     b <- ZIO.service[ServiceB]
  } yield new ServiceCImpl(a, b)
}

Are these two snippets doing the same thing? If not, what is the difference? If yes, why are there two of them? When would you use one over the other?

1

There are 1 answers

2
Gaël J On

In your case, they are doing the same thing. And there's actually a 3rd way with ZLayer.fromFunction:

ZLayer.fromFunction(ServiceCImpl _)
// or:
ZLayer.fromFunction((a: ServiceA, b: ServiceB) => new ServiceCImpl(a,b))

Which is IMHO the simplest.


What is the difference then?

  • ZLayer.scoped is to be used when the service you're creating needs some scoped resources (like opening a file and closing it automatically when "stopping" the service, or a database connection)
  • ZLayer.fromZIO is to be used when there's no resource to manage but still there are potential errors and creating the service is represented as a ZIO
  • ZLayer.fromFunction is to be used when none of the above apply, that is when creating the service just needs some other dependencies but it cannot fail and doesn't need to manage any resource

See also ZLayer reference documentation.