[Evolution] Ktor locations nested classes
See original GitHub issueSubsystem ktor-locations
Description We are going to develop and expand ktor Locations (Type-Safe routing https://ktor.io/servers/features/locations.html). One of the directions to improve is Kotlin Multiplatform. The most obvious way of migration to MPP is to use kotlinx.serialization in locations. Due to the limited reflection capabilities of non-JVM targets, there are things that not so easy to implement. On the other hand, there are questionable features that may lead to issues. One of the problematic features is nested location classes and nested location objects.
What we are thinking of to change:
- a nested location class should always have a property of the outer class or object
- nested objects in objects are not allowed
The motivation for the first point is the fact that a location class nested to another, makes no sense without the ability to refer to the outer class. Consider the following example:
@Location("/api/{version}")
class Api(val version: Int) {
@Location("/user/{id}")
class User(val id: String, val api: Api = Api(1)) {
// here API presence looks required,
// otherwise, there is no way to find a version value
// so now we demand the api parameter to exist
}
}
The other point is that one can’t just move a nested class outside without additional manual changes:
@Location("/root")
class Outer {
@Location("/child")
class Child // it is tied to /root/child path
}
@Location("/child")
class Child // this is tied to just /child
@Location("/child2")
class Child2(val outer: Outer) // -> /root/child2
The cause of the second change is that objects should be symmetric with classes, and one can’t add a constructor property to an object. The unfortunate consequence is that one can’t write like this anymore:
@Location("/api")
object Api {
@Location("/info")
object Info
}
Should be migrated to the following:
@Location("/api")
object Api {
@Location("/info")
class Info(val api: Api = Api)
// the api parameter is required, weird isn't it
}
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
What is the technical reason this cannot be special cased:
An asymmetric case I stumbled upon with the current design is that the current builders ie.
get<Location>(){ .. }
also work nested:path("/fooo/") { get<Location> {} }
. This context isnt preserved so one cannot always assumehref(location)
will give the routeable path that lead to the location. I am not sure what to do about it but it bit me.One solution is obviously to disallow nested location routing.