Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Route.inject() help in koin-ktor #128

Closed
ValentinTrinque opened this issue May 15, 2018 · 4 comments
Closed

Support Route.inject() help in koin-ktor #128

ValentinTrinque opened this issue May 15, 2018 · 4 comments
Labels
ktor status:checking currently in analysis - discussion or need more detailed specs

Comments

@ValentinTrinque
Copy link

Note: I am a Kotlin beginner

I am currently working on integrating an HTTP API using ktor, using koin-ktor. While designing my endpoints routing, I wanted to inject the dependencies at the Route level instead of Application level. Indeed, I split my Routes in seperate files, one for each resource :

api/Application.kt

fun Application.endpoints() {
    routing {
        v1()
    }
}

fun Routing.v1() {
    route("/api/v1") {
        users()
    }
}

api/v1/Users.kt

fun Route.users() {
    val usersQueryRepository: UsersQueryRepository by inject()

    get("/users") {
        val users: List<UserDto> = usersQueryRepository.list()

        call.respond(users)
    }
}

Your library implements inject() (& co.) helpers at Application level only. I was thinking about making this available at Route level.

Here is a working implementation:

inline fun <reified T> Route.inject(name: String = "") =
        kotlin.lazy { (StandAloneContext.koinContext as KoinContext).get<T>(name, emptyParameters()) }

What do you think ? I would be glad to help!

@scottsteen
Copy link

What I would rather see is the functions defined in KoinComponent to not be associated with an interface. This would remove the need for the koin-ktor project. I plan to open another issue with this request though. Kotlin actually allows you to define functions that do not belong to a class!

To get around the limitation you face is to create a Kotlin object that implements the KoinComponent interface. This way I can call inject() anywhere I need to.

Example:

object KoinProxy : KoinComponent
...
val usersQueryRepository: UsersQueryRepository by KoinProxy.inject()
...

Something else to consider is to call startKoin() in the object's init block. E.g.

object KoinProxy : KoinComponent {
    init {
        startKoin(listOf(your_context))
    }
}

@arnaudgiuliani arnaudgiuliani added ktor status:checking currently in analysis - discussion or need more detailed specs labels May 17, 2018
@arnaudgiuliani
Copy link
Member

Hello @scottsteen

What I would rather see is the functions defined in KoinComponent to not be associated with an interface.

This is another issue. We'll continue here about ktor Route API integration.

@roelandxyz
Copy link

For me this is not usable because the inject happens at application start and not on a http request.
I would like to create a new service at every request to that route.
For now I do the inject in every get() method instead. Is there a better way?
Maybe this is more a Ktor problem then a Koin problem.

This is the extension method I use for now:

inline fun <reified T> PipelineContext<Unit, ApplicationCall>.inject(name: String = "") =
        kotlin.lazy { (StandAloneContext.koinContext as KoinContext).get<T>(name, emptyParameters()) }

@arnaudgiuliani
Copy link
Member

@Baresse added the extensions for Route &
Routing. will be available in 1.0.0-beta-3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ktor status:checking currently in analysis - discussion or need more detailed specs
Projects
None yet
Development

No branches or pull requests

4 participants