https://kotlinlang.org logo
Title
r

Rui

10/19/2020, 3:01 PM
Hello everyone, I have a question about extracting routes. So I extracted them and put them in separate files, but the question is, if these different routing all need to hold the references to same objects, where to put those objects? More specifically, I have two routing files called Order.kt and Item.kt, and both of them need to use an instance of ItemService class. Then where should I put this
lateinit var itemService: ItemService
For now this is what I do, in Order.kt file:
lateinit var itemService: ItemService
fun Route.order() {
  post<Order> {
    init(...)
  }

  get<Order> {
    init(...)
  }
}

init(...) {
  itemService = ItemService(...)
}
and in Item.kt file
fun Route.item() {
  post<Item> {
    init(...)
  }
  get<Item> {
    init(...)
  }
}
Basically I put those common objects and their initialization method in one of the routing files, and other routing file can have direct access to those objects and methods. I wonder what is the more proper way of organizing this? Appreciate any kinds of input !
m

Marc Knaup

10/19/2020, 3:07 PM
You could simply pass whatever dependencies
Route.order()
needs to the function as parameters. Alternatively you could use a dependency injection framework (and pass that as a function parameter). You could also write a feature that puts references into the call and makes them available as an extension property to the call.
r

Rui

10/19/2020, 3:13 PM
@Marc Knaup those objects in need will only be initialized when one of the routing gets called, with values from http parameters. Please note the init(...) method. In that case, what's the best practice?
m

Marc Knaup

10/19/2020, 3:15 PM
Hmm I think I don’t fully understand your issue. Why don’t you call
init()
in
post<Order> { … }
for example and return the
ImageService
(and others)?
both of them need to use an instance of ItemService class
and
those objects in need will only be initialized when one of the routing gets called, with values from http parameters
are conflicting. Should they share an instance of not? If they should share one, then the instance shouldn’t depend on request parameters 🤔
r

Rui

10/19/2020, 3:24 PM
@Marc Knaup or to put it this way, all the routing needs to use ItemService, but they need to create their own ItemService object based on parameter values in the http request. Please see how I put itemService as a lateinit var, and each routes will initialize it with values from http request when getting called, that's why I call init(...) in all the routes
m

Marc Knaup

10/19/2020, 3:25 PM
Yeah it will definitely not work that way. All routes will overwrite each other’s
itemService
That’s why I’m asking about a simple
val imageService = init(…)
In the routes
r

Rui

10/19/2020, 3:29 PM
@Marc Knaup yes in my example itemService gets overridden by each other, but somehow it works fine. I can change it to
val imageService = init(…)
then where should I put the definition of init(...) method?
m

Marc Knaup

10/19/2020, 3:30 PM
That’s the thing with race conditions. They may or may not cause mayhem 😄 It will likely cause issues randomly. The definition of
init
you can have wherever you want. if it just initializes an
ImageService
it should be somewhere nearby. It’s difficult to say without knowing more.
r

Rui

10/19/2020, 3:43 PM
@Marc Knaup thanks for answering!