{"id":15343812,"url":"https://github.com/rocketraman/bootable","last_synced_at":"2025-04-06T13:28:56.929Z","repository":{"id":57722449,"uuid":"363045930","full_name":"rocketraman/bootable","owner":"rocketraman","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-02T20:20:56.000Z","size":399,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T21:23:06.159Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rocketraman.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-30T06:19:46.000Z","updated_at":"2025-04-02T20:20:18.000Z","dependencies_parsed_at":"2025-04-02T21:21:04.451Z","dependency_job_id":"45987e3e-0377-43f8-9dff-bd190d682a05","html_url":"https://github.com/rocketraman/bootable","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocketraman%2Fbootable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocketraman%2Fbootable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocketraman%2Fbootable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocketraman%2Fbootable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rocketraman","download_url":"https://codeload.github.com/rocketraman/bootable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247487769,"owners_count":20946820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T10:51:28.948Z","updated_at":"2025-04-06T13:28:56.920Z","avatar_url":"https://github.com/rocketraman.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"= Bootable\n\nimage:https://img.shields.io/maven-central/v/com.github.rocketraman.bootable/boot[Maven Central,link=\"https://search.maven.org/search?q=g:com.github.rocketraman.bootable\"]\nimage:https://img.shields.io/github/license/rocketraman/bootable[\"GitHub license\",link=\"https://github.com/rocketraman/bootable/blob/HEAD/LICENSE\"]\n\nA simple opinionated framework for booting applications.\nIntended to be much simpler than Spring Boot or even modern iterations like Quarkus and Micronaut, but still featureful enough to be useful.\nHandles stopping, starting, lifecycle management, logging, configuration, and other basic reusable components, and integrates Kodein-DI.\n\nAn important element of simplicity is to prefer the use of explicit references and configuration.\nSpring Boot's runtime discovery of components and plugins via annotation and reflection is https://www.youtube.com/watch?v=SxdOUGdseq4[easy but not simple].\nTo use Spring Boot, you have to understand two layers: the libraries underneath Spring, as well as all of Spring's own auto-magic annotations.\nToo many projects use Spring Boot, but fail to understand the hidden complexities, resulting in nasty bugs in production.\n\nThe goal of Bootable is to provide a minimal framework for running Kotlin (or Java?) applications, and then gets out of your way.\n\nUseful reading:\n\n* https://dantanner.com/post/spring-rites/[Spring Rites: A caution against annotation-based web frameworks] by Dan Tanner\n\n== Features\n\n* Creates a DI context.\n* Manages the lifecycle of application services.\n* Allows registration of lifecycle controllers, which can be used to control the lifecycle of application services in various ways.\nThe basic built-in implementation of this is the `AppStartStopLifecycleController` which starts application services on app start, and shuts them down on app close, in priority order.\nAnother basic implementation, intended to be used in conjunction with `AppStartStopLifecycleController`, is the `StopSignalHandlerLifecycleController`, which registers signal handlers, which, when received, cleanly shuts the system down.\nOther implementations are possible: for example starting/stopping services at runtime based on a command system, like start/stop messages from RPCs or web requests.\n\n== Modules\n\nBootable is modular, and provides a number of modules to help you build your application.\nThe core module is simply `com.github.rocketraman.bootable:boot`, which provides the basic application lifecycle features of Bootable.\nAdd additional modules as you wish.\n\n[[Configuration]]\n=== Configuration\n\n==== cfg4k (Deprecated)\n\nSee https://github.com/rocketraman/cfg4k[cfg4k].\n\nAdd this module to your project to use cfg4k for configuration.\nNote that while cfg4k works well, it is unmaintained.\nWe recommend using Hoplite instead.\n\nxref:./boot-config-cfg4k/README.adoc[Documentation]\n\n==== Hoplite\n\nSee https://github.com/sksamuel/hoplite[hoplite].\n\nAdd this module to your project to use Hoplite for configuration.\n\nxref:./boot-config-hoplite/README.adoc[Documentation]\n\n=== Environment\n\nWARNING: Over-using this abstraction is a code smell.\n\nThis module simply exposes a strongly-typed global `environment` variable to the system, which is initialized via the configuration system when `environmentConfigModule` is imported.\n\nThis should be *rarely* used, but sometimes it is useful to have a way to identify the environment e.g. dev, test, prod, or other.\nGood use cases are tagging metrics with the environment, or extremely complex environment-specific configuration that can't be easily abstracted using one of the \u003c\u003cConfiguration\u003e\u003e modules.\n\nNote that this is also useful in a JavaScript environment, where the environment may be bound to a global variable by something like https://github.com/mrsteele/dotenv-webpack[dotenv-webpack].\nThe environment abstraction may be used to abstract away the underlying details of this binding in a way that can be used in both frontend and backend in the common code source set.\n\nNOTE: We currently do not publish multi-platform versions of these modules, but may do so in the future.\n\n=== Logging (Log4j2)\n\nThis module provides all the necessary imports to configure Log4j2 as the logging system for the application.\nIt provides good default logging layouts, and supports multiple output types e.g. plain (both color and not), JSON, and GCloud.\nSee https://github.com/rocketraman/bootable/blob/HEAD/boot-logging-log4j2/src/main/kotlin/com/github/rocketraman/bootable/logging/log4j2/LoggingType.kt[LoggingType].\n\n=== Server HTTP (Ktor)\n\nProvides a basic Ktor service abstraction with Bootable lifecycle integration i.e. the server starts and stops with the application.\nDoes not attempt to configure Ktor in any significant way — this is left to the user.\nSee https://github.com/rocketraman/bootable/blob/HEAD/boot-server-http-ktor/src/main/kotlin/com/github/rocketraman/bootable/server/http/ktor/KtorService.kt[KtorService].\n\n== How to Use (Basic)\n\nSee the projects in the `examples` directory.\n\n* Application components that have a lifecycle should implement `AppService` or `AdvancedAppService`, and these should be bound into the DI context via `bindAppService`.\n* Start the system with the `boot` function.\n\n== How to Use (Advanced)\n\n* Customize with additional `LifecycleController` implementations.\n* Override the `boot` function to achieve more custom behavior.\n\n== Design\n\n=== Why Dependency Injection? Why Kodein-DI?\n\nThe heavy-weight nature of DI frameworks like Spring has given DI a bit of a bad rap.\n\nKodein-DI is a simple, lightweight, and fast dependency injection framework.\n\nMany people argue that DI is unnecessary with Kotlin, and that simple constructor injection is sufficient.\nThis is absolutely true for small projects, but as a project grows, inevitably the need for modularity and more complex component scopes arises.\nConsider a multi-module app, each module of which exposes one or more `AppService` implementations without having any code be aware of all the possible implementations in advance.\n\nAll the modules that Bootable provides connect together via Kodein-DI.\n\nThat being said, nothing Bootable does is highly tied to Kodein-DI.\nInternally, Bootable is DI agnostic.\nSee, for example, the main framework class https://github.com/rocketraman/bootable/blob/HEAD/boot/src/main/kotlin/com/github/rocketraman/bootable/boot/Bootable.kt[Bootable.kt] which does the basic work of starting and stopping the system.\nThere are no references to any DI framework — it simply uses constructor injection.\n\nTo skip use of Kodein-DI, it is simple to use this class directly rather than the https://github.com/rocketraman/bootable/blob/HEAD/boot/src/main/kotlin/com/github/rocketraman/bootable/boot/BootableModule.kt#L19[`boot`] convenience function which initiates the system via Kodein-DI.\nEach module exposed by Bootable via Kodein-DI modules can also be exposed via other frameworks, or no framework at all.\n\nTherefore, in the future Kodein-DI may be replaced in Bootable with some other DI-agnostic approach such as context injection or even basic constructor injection.\n\n== TODOs\n\n* [ ] Replace unmaintained https://github.com/rocketraman/cfg4k[cfg4k] with https://github.com/sksamuel/hoplite[hoplite] for configuration\n* [ ] Do we need really Kodein-DI? At the moment, only the `boot` function uses it, and that could easily be \"fixed\".\nThe config and environment modules also expose Kodein modules, but could just as easily not do so.\n* [ ] Multiple logging implementations for different scenarios, loggingInit via `ServiceLoader` — or perhaps remain opinionated and do not do this?\n* [ ] Create a boot-server-http-ktor-cohort module using https://github.com/sksamuel/cohort[Cohort]\n* [ ] Update the ktor example to integrate https://github.com/sksamuel/hoplite[Kompendium] — this is outside the scope of Bootable, but it would be a good example of how to integrate Bootable with other libraries\n* [ ] Make multiplatform — some modules are backend only e.g. Hoplite, Log4j2, but others could easily be adapted for multiplatform usage\n\n== Author\n\nRaman Gupta \u003crocketraman@gmail.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frocketraman%2Fbootable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frocketraman%2Fbootable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frocketraman%2Fbootable/lists"}