https://kotlinlang.org logo
Title
r

Rohde Fischer

02/01/2021, 7:36 AM
so how do I structure a KTor app in a reasonable way with a DI? I seems I'm currently fighting the framework due it's heavy use of extension methods (I am also highly skeptical of that design choice, but for now I will go with the flow and give it a chance to grow). Say I have a
FooRoute
and want to make use of the
FooService
interface, what is a reasonable way to do that? Currently I'm around:
class FooRoute @Inject constructor(application: Application, foo: FooService) {
    init {
        // do "magic" here
    }
}
but I also want to structure my code in nicely designed methods etc. so there's a clear structure to it and all that
I guess I could also inject FooRoute into the MainApplication part of my application, but then I'd have to inject of of those in there, but then I'd have to inject every single service I design, and it seems it would end up in a lot of boilerplate I'd like to avoid
b

Big Chungus

02/01/2021, 7:48 AM
I'm using kodein with ktor and it's lovely. No injections, no reflection.. everything is done via kotlin delegates and reified inline functions. Strongly recommend it for ktor apps
Here's an example . Note that it's quite outdated, so take it with a grain of salt, but it should give you an idea of how things look like with kodein
r

Rohde Fischer

02/01/2021, 7:58 AM
I was going for Guice for now, to not introduce too many "young" frameworks in one go, but I'll take a look, fortunately I'm not that far in, so the change would be easy to make. That said, so I am a bit puzzled why KTor went with a heavy use of extension functions rather than standard injectable interface based approach. For now (and in general), I'm not overly impressed by extension methods except for those cases where I need something beyond the norms of a framework outside my control. That said, I will go with the flow for now, but so far it feels like an anti patterns to me
b

Big Chungus

02/01/2021, 8:00 AM
Ktor tries to avoid reflection as much as possible. Extension functions helps a bit with that while maintaining a convenient dev experience
👍 1
But that's just my 2 cents
Also kodein is one of the first kotlin di frameworks, so not that young
There's also koin if you want to compare
Also ktor is moving away from oop (java) and imperative style (spring), so it might feel weird for people comming from java
r

Rohde Fischer

02/01/2021, 8:12 AM
well I have been doing Kotlin for 2 years now (but yes with a quite heavy Java background), but using Spring indeed (customer requirement, no choice) I guess I'll have a try, you are at least quite right on one account, reflection is also nasty, and reflection is needed to accommodate the standard
@Inject
annotations etc. One thing I like with them though is that they are a standard, so at least in principle, I should be able to replace e.g. Guice with Spring, should it turn out that Guice is a bad choice. I guess the Kodein approach will be less interchangable?
b

Big Chungus

02/01/2021, 8:13 AM
Correct, kodein is purely declarative and doesn't use annotations, so you'd end up getting locked in to the framework
I guess it's a matter of how deep you want to invest in kotlin ecosystem. Kotlin-first frameworks are always a nicer option for kotlin projects, but they make migrating back to java or interoping with java frameworks harder
r

Rohde Fischer

02/01/2021, 8:31 AM
migrating back to Java won't be an issue 🙂 I'm more thinking of the general advantages of a loose coupling. I mean the entire point of DI and IOC is exactly to loosen the coupling and make it based on interfaces, which is also why it's nice that Java did (although way too late) make standard annotations to DI, so one can actually have a loose coupling to the DI framework. Of course, as we already concluded, the cost of that is reflection 😕 I guess there are pros and cons to everything
@Big Chungus oh well, I'll give Kodein the chance, if I'm to go with the flow, I might as well, and then I'll also be better informed whether it be the my initial caution is valid or not 🙂 Although I will veto their use of variable injection in their examples and go for constructor injection
j

Jorge R

02/01/2021, 10:40 AM
Ey @Big Chungus, could you please explain a bit what the Backend part of the repository you’ve shared is doing? I’m trying to see the benefits of using Kodein and I would appreciate some context. You said it is quite outdated, I’ve just wanted to compare Kodein with Koin (if that makes sense nowadays)
@Rohde Fischer here you can find another example about how to setup a full architecture for your Ktor server. https://github.com/mathias21/KtorEasy And an article talking about it to explain the different layers: https://medium.com/swlh/architecture-proposal-to-build-servers-with-ktor-1069bfaf2926 It is using Koin with Ktor integration. I hope this helps. Also any feedback is appreciated!
🙌 2
There is an example of testing for each layer (except configuration layers), so you can test your business logic.
b

Big Chungus

02/01/2021, 10:52 AM
@Jorge R that repo is basically a fullstack webapp that you can use to connect to your Hazelcast (in-memory database, similar to Redis) cluster to directly interact with it's data via webui. The backend simply takes requests from the UI and serves CRUD operations on cluster's maps.
j

Jorge R

02/01/2021, 10:56 AM
Thank you! I’ve seen a lot of dynamic stuff there, a bit hard to follow without some context. Also injecting route modules seems quite advanced 😄 (I need to think if I should incorporate something like that to my repo ☺️)
r

Rohde Fischer

02/01/2021, 12:20 PM
ah thanks both of you, it's a huge help, and it's really appreciated
b

Big Chungus

02/01/2021, 1:35 PM
Looks like kodein even supports @Inject afterall https://docs.kodein.org/kodein-di/7.2/extension/jsr330.html
r

Rohde Fischer

02/02/2021, 2:51 PM
@Big Chungus ohh nice, thanks a lot (and sorry for responding late - meetings...) But that is really nice, I ended up deciding as long as it's constructor injection it will at least be low risk due to the fairly easy transformation, but I guess that's not even needed. Thanks a lot
👏 1