Is there a simple way to collect all existing Rout...
# ktor
f
Is there a simple way to collect all existing Routing endpoints? I am using the next solution, as I couldn't find any simpler way to get such information:
Copy code
@Serializable
public data class RouteInfo(val path: String, val method: String)

internal fun Application.collectRoutes(): List<RouteInfo> {
    val routes: MutableList<RouteInfo> = mutableListOf()

    // Helper function to recursively traverse and collect routes.
    fun RoutingNode.collect() {
        if (this.selector is HttpMethodRouteSelector) {
            val method: String = (this.selector as HttpMethodRouteSelector).method.value
            val path: String = this.extractRoutePath()
            val routeInfo = RouteInfo(path = path, method = method)
            routes.add(routeInfo)
        }
        this.children.forEach { it.collect() }
    }

    // Start collecting from the root route.
    this.routing { }.children.forEach { it.collect() }

    return routes.sortedWith(
        compareBy(
            { it.path },
            { it.method }
        )
    )
}

private fun RoutingNode.extractRoutePath(): String {
    val segments: MutableList<String> = mutableListOf()
    var currentRoute: Route? = this

    // Traverse the parent chain of the current route and collect path segments.
    while (currentRoute is RoutingNode) {
        val selector: RouteSelector = currentRoute.selector

        when (selector) {
            is PathSegmentConstantRouteSelector -> selector.value
            is PathSegmentParameterRouteSelector -> "{${selector.name}}"
            is PathSegmentOptionalParameterRouteSelector -> "{${selector.name}?}"
            is PathSegmentWildcardRouteSelector -> "*"
            is TrailingSlashRouteSelector -> ""  // Ignored for path construction
            is HttpMethodRouteSelector -> ""     // Ignored for path construction
            else -> ""
        }.let { segment ->
            if (segment.isNotEmpty()) {
                segments.add(segment)
            }
        }

        currentRoute = currentRoute.parent
    }

    return segments.asReversed().joinToString(separator = "/", prefix = "/").trimEnd('/')
}
d