What is ZIO?
ZIO is a Scala zero-dependency library for asynchronous and concurrent programming. It enables you to create applications that are scalable, resilient and responsive to your business’s demands.
ZIO
is built around the ZIO
data type. These data types have three parameters and are referred to as ZIO[R, E, A]
.
R
stands for environment type and the effect requires an R-type environment. When this type
parameter is set to Any
then the effect has no limitations because it can be run with any value or with Unit
.
E
stands for failure kind with a value of type E then the effect may fail. This effect can be used with Throwable
or Nothing
and Nothing
means the effect cannot fail.
A
stands for success and the effect will succeed with the type A
. If this type is set to Unit
then the effect will yield no relevant information. If it is set to Nothing
then the effect will run indefinitely or until failure.
You can click here to read more about ZIO and ZIO Datatypes.
ZLayer
A ZLayer[-RIn, +E, +ROut]
represents an application layer; each layer in an application can require some services as input RIn
and produces some services as output ROut
.
Like everything else, ZIO
treats services as an effect. As any service may require dependency [RIn]
and produces an effect[ROut]
.
For sake of better understanding we will look into a small application that will help us understand ZLayer
.
Understanding ZLayer with Example
The application is simple as it counts the number of words present in the given list of URLs. We will divide the application into two services->
- This first service is named
SourceReader
. The service opens the source then reads the content of a file and closes the sources. WordCounter
service takes the content of the file and produces a map with words which has the total occurrence of the word.
Here the SourceReader
service does not require any resources therefore construction of the service layer is simple. We just need to wrap the constructor of service inside ZLayer.succeed()
. ZLayer.succeed()
converts instantiation of service to functional effect which return SourceReaderEnv
.
WordCounter
is different from SourceReader
Service as it is dependent on it. Therefore SourceReader
availability is important for the construction of WordCounter
service. To help us in this we will require ZLayer.fromService()
. ZLayer.fromService[SourceReader.Service, WordCounter.Service]
makes sure SourceReader
is available for the construction of WordCounter
.
To build a single service which requires numerous services. We use ZLayer.fromServices()
which is similar to ZLayer.fromService()
.
ZIO.accessM()
makes sure to get the instance of service and make methods of services available.
Now the only thing left to make is layers of SourceReader
and WordCounter
compose each other. Which will return an instance of the WordCounter
service with ZIO.live
method we created earlier. The construction of wordCounterLayer
is also known as vertical composition in ZIO
.
ZIO.provideLayer()
helps in providing the required layer. It is similar to dependency injection but instead of providing an instance of service. ZLayer
wraps the instance and provides the effect of the instance which is lazy and immutable.
You can click here to follow the official documentation for more information on ZIO and ZLayer.
You can also click here for demo application on ZLayer
.