How do I smartly manage larger scale Applications ...
# server
c
How do I smartly manage larger scale Applications with ktor?
Copy code
fun Application.module() {
// load modules
}
If I had a Project with ~50 modules/plugins/services to load, would it be rational to user ktor, or is it mainly designed for microservices?
a
If I daresay the 50 module project is a monolith, then it does tend to be easier to keep a monolith sane with a far more opinionated framework like Spring. But there's no reason Ktor can't handle a project that size when combined with good architectural sense. In fact, Ktor will make it much easier to maintain good test coverage. However, I can't really answer your original question, since I don't work with monoliths anymore. My only suggestion is to try keep it as modular as possible, with a flat dependency hierarchy.
c
Im experimenting with spring and ktor in my company. I will try to add methods with a specific postfix like "module" to Application. With using reflections, I could look for those functions and dynamicly execute them within module. Maybe I am on for something ^^
a
I don't personally think 50 methods is worth using reflection for. I never liked how in Spring you could never quickly tell if an unused class or method was actually unused or just invoked reflectively.
c
You can create each module as a different
Application
extension function, and load them all in the configuration file:
Copy code
ktor {
    application {
        modules = [ com.example.ApplicationKt.module1,
                    com.example.ApplicationKt.module2,
                    org.sample.SampleKt.module3 ]
    }
}
Each module is independent and can have its own plugins, etc. https://ktor.io/docs/modules.html
👀 2
d
We have a modulith with Ktor and use Koin to split the application into separate modules. This way it is easy enough to keep each module in a separate gradle module and only the final server needs to reference the module's koin module.
Copy code
install(Koin) {
        slf4jLogger(level = Level.INFO)
        modules(
            module {
                single { this@main }
                single { this@main.environment.config }
            },
            module {
                single { openTelemetry.getTracer("our-app", "1.0.0") }
            },
            module {
                single { unleashService } bind ToggleService::class
            },
            metricsKoinSetup(),
            configKoinSetup(serverConfig),
            databaseKoinSetup(),
            coreKoinSetup(),
            kafkaKoinSetup(),
            com.company.othermodule.setup.koinAuthModule,
            com.company.othermodule.setup.koinUserModule,
...
And yes, it is annoying that the word
module
is used everywhere for different things ...
2
c
@Dominik Sandjaja I did not knew that there was such thing as Koin, that helps me a lot. I also thought about defining seperate atomar gradle modules with nearly 100 % test coverage. Could be much easear to maintain each segment.
👍 1