Hello everyone, I have a question about extracting...
# ktor
r
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
Copy code
lateinit var itemService: ItemService
For now this is what I do, in Order.kt file:
Copy code
lateinit var itemService: ItemService
fun Route.order() {
  post<Order> {
    init(...)
  }

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

init(...) {
  itemService = ItemService(...)
}
and in Item.kt file
Copy code
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
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
@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
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
@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
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
@Marc Knaup yes in my example itemService gets overridden by each other, but somehow it works fine. I can change it to
Copy code
val imageService = init(…)
then where should I put the definition of init(...) method?
m
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
@Marc Knaup thanks for answering!