Toolkit is a lightweight and non-intrusive open-source library designed to simplify the development of typed and declarative applications in Scala.
It offers a functional approach to building applications by managing resources and dependencies, allowing developers to focus on the core aspects of their application logic.
Read this article about this library: Semantic of a functional app in Scala
Please, drop a ⭐️ if you are interested in this project and you want to support it.
Resources --build--> Dependencies --> [Finalize Resources] --build--> App Logic -> [Finalize Dependencies]
-
Resource Management: Toolkit simplifies the management of application resources, such as configuration settings, logging, and custom resources. By abstracting away the resource handling, it reduces boilerplate code and provides a clean and concise syntax for managing resources.
-
Dependency Injection: The library provides a straightforward way to handle application dependencies. It allows you to define and inject application-specific services and repositories, encouraging modular and testable code.
-
Declarative Syntax: Toolkit promotes a declarative coding style, where you can describe the structure and behavior of your application in a clear and concise manner. This leads to code that is easier to understand, reason about, and maintain.
- Resources are released before providing the app execution.
- Dependencies are released at the end of the app execution as defined as
Resource[F, *]
. - If you need to run an infinite task using
provide*
you should useF.never
or equivalent to keep the task running.
To get started with Toolkit, follow these steps:
- Installation: Include the library as a dependency in your Scala project. You can find the latest version and installation instructions in the Toolkit GitHub repository.
libraryDependencies += "com.github.geirolz" %% "toolkit" % "0.0.11"
- Define Your Application: Create a new Scala objects or classes that represents your application dependencies and resources.
import cats.Show
import cats.effect.{Resource, IO}
import com.geirolz.app.toolkit.*
import com.geirolz.app.toolkit.logger.ConsoleLogger
import com.geirolz.app.toolkit.novalues.NoResources
// Define config
case class Config(host: String, port: Int)
object Config:
given Show[Config] = Show.fromToString
// Define service dependencies
case class AppDependencyServices(kafkaConsumer: KafkaConsumer[IO])
object AppDependencyServices:
def resource(using AppContext.NoDepsAndRes[SimpleAppInfo[String], ConsoleLogger[IO], Config]): Resource[IO, AppDependencyServices] =
Resource.pure(AppDependencyServices(KafkaConsumer.fake))
// A stubbed kafka consumer
trait KafkaConsumer[F[_]]:
def consumeFrom(name: String): fs2.Stream[F, KafkaConsumer.KafkaRecord]
object KafkaConsumer:
import scala.concurrent.duration.DurationInt
case class KafkaRecord(value: String)
def fake: KafkaConsumer[IO] =
(name: String) =>
fs2.Stream
.eval(IO.randomUUID.map(t => KafkaRecord(t.toString)).flatTap(_ => IO.sleep(5.seconds)))
.repeat
- Build Your Application: Build your application using the Toolkit DSL and execute it. Toolkit takes care of managing resources, handling dependencies, and orchestrating the execution of your application logic.
import cats.effect.{ExitCode, IO, IOApp}
import com.geirolz.app.toolkit.*
import com.geirolz.app.toolkit.logger.Logger
object Main extends IOApp:
override def run(args: List[String]): IO[ExitCode] =
App[IO]
.withInfo(
SimpleAppInfo.string(
name = "toolkit",
version = "0.0.1",
scalaVersion = "2.13.10",
sbtVersion = "1.8.0"
)
)
.withConsoleLogger()
.withConfigF(IO.pure(Config("localhost", 8080)))
.dependsOn(AppDependencyServices.resource)
.beforeProviding(ctx.logger.info("CUSTOM PRE-PROVIDING"))
.provideOne(
// Kafka consumer
ctx.dependencies.kafkaConsumer
.consumeFrom("test-topic")
.evalTap(record => ctx.logger.info(s"Received record $record"))
.compile
.drain
)
.onFinalize(ctx.logger.info("CUSTOM END"))
.run(args)
Check a full example here
For detailed usage examples and API documentation, please refer to the Toolkit Wiki.
For a comprehensive list of integrations between Toolkit and other popular libraries, please refer to the integrations.md file.
It provides an overview of the integrations available, including libraries such as PureConfig, Log4cats, Odin, and more.
Each integration showcases the benefits and features it brings to your Toolkit-based applications, enabling you to enhance functionality and streamline development. Explore the integrations to leverage the power of Toolkit in combination with other powerful libraries.
If you are using Toolkit in your company, please let me know and I'll add it to the list! It means a lot to me.
We welcome contributions from the open-source community to make Toolkit even better. If you have any bug reports, feature requests, or suggestions, please submit them via GitHub issues. Pull requests are also welcome.
Before contributing, please read our Contribution Guidelines to understand the development process and coding conventions.
Please remember te following:
- Run
sbt scalafmtAll
before submitting a PR. - Run
sbt gen-doc
to update the documentation.
Toolkit is released under the Apache License 2.0. Feel free to use it in your open-source or commercial projects.
We would like to thank all the contributors who have made Toolkit possible. Your valuable feedback, bug reports, and code contributions have helped shape and improve the library.
For any questions or inquiries, you can reach out to the maintainers of Toolkit via email or open an issue in the GitHub repository.
Happy coding with Toolkit!