https://kotlinlang.org logo
#ktor
Title
# ktor
b

bbaldino

04/29/2022, 4:59 PM
Is there a good way to scope an
Application.configureRoutes()
-type method within a class to be able to add additional context? For example, I want to be able to fire events when a new websocket is established, so want a way to store a sort of ‘event emitter’, and therefore allow external entities to be able to subscribe to those events. I think maybe the new
Context Receivers
would handle this? But looking for another way since those are still experimental.
For example:
Copy code
class MyClass {
    private val eventHandlers = mutableListOf<EventHandler>()

    fun addEventHandler(handler: EventHandler) {
        eventHandlers += handler
    }

    fun Application.configureRoutes() {
        webSocket("/ws") {
            eventHandlers.forEach { it.websocketConnected() }
            ...
        }
    }
}
l

Landry Norris

05/01/2022, 8:08 PM
Does making MyClass an object work? I believe you can import extension functions that are members of an object. Alternatively, you could make the Application a parameter.
b

bbaldino

05/02/2022, 3:11 PM
Making the context a parameter to the function was my plan for a fallback…I haven’t tried an object. I’m hoping for a class, though, because generally I find that easier for things like testing, but admittedly I haven’t used plain objects much for something like this.
j

Joost Klitsie

05/04/2022, 2:47 PM
I think it makes sense to not have the MyClass wrap the eventHandlers and the routing, as part of a separation of concerns. You can of course do that and it will look like:
Copy code
fun Application.module() {
    val myClass = MyClass()
    with(myClass) {
        configureRoutes()
    }
}
But I think it is better to pass in the myClass object as a parameter (sort of a dependency) to configureRouts
Copy code
fun Application.module() {
    val myClass = MyClass()
    configureWebSockets(myClass)
}

fun Application.configureWebSockets(myClass: MyClass) {
    webSocket("/ws") {
        myClass.onWebSocketConnected() // <-- do something there within your myClass
    }
}
to be fair it may depend on the usecase 😄
I have a project where I instantiate backend services and they indeed have an
fun Application.installRouting()
in these service classes
5 Views