Skip to content

A Scala 3, lightweight and functional non-intrusive library to build typed and declarative Scala application with managed resources and dependencies

License

Notifications You must be signed in to change notification settings

geirolz/toolkit

Repository files navigation

Toolkit

Build Status codecov Codacy Badge Sonatype Nexus (Releases) Scala Steward badge Mergify Status GitHub license

logo

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.

Features

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.

Notes

  • 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 use F.never or equivalent to keep the task running.

Getting Started

To get started with Toolkit, follow these steps:

  1. 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"
  1. 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
  1. 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.

Integrations

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.

Adopters

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.

Contributing

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.

License

Toolkit is released under the Apache License 2.0. Feel free to use it in your open-source or commercial projects.

Acknowledgements

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.

Contact

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!