Cookie Consent by Free Privacy Policy Generator 📌 Kotlin Routing - routing everything


✅ Kotlin Routing - routing everything


💡 Newskategorie: Programmierung
🔗 Quelle: dev.to

Kotlin multiplatform (KMP) is a reality for any developer working with Kotlin. Mainly people working with Android. KMP has incresed since it was beta and now is stable and production-ready.

In paralel Jetbrains has created a lot of KMP frameworks that are awesome. One of them is Ktor that helps "create asynchronous client and server applications."

Ktor has an awesome routing structure on your server engine and supporting all the whole things related to an URI.

As a mobile developer I saw that in any mobile framework the navigation almost scale to a routed version that works with path, parameters, all thing related to URI.

I think that the Ktor team has not thought that your routing system could be exported to scenarios out of the Client or Server networks.

KMP use cases increasing, developers migrating or creating your projects to KMP, no routing system or navigation available to KMP (Except Voyager), that was the opportunity to create one.

  • The Kotlin Routing
  • Named Routing
  • Routing by Method
  • Group Routes
  • Path Pattern
  • Route Details
  • Working with Parameters
  • Redirect Routes
  • On demand handling
  • Nested Routing
  • Conclusion
  • Bonus 1 - Routing Natives
  • Bonus 2 - Deeplinks
generated with Summaryze Forem 🌱

The Kotlin Routing

I'm not good with names. So I put kotlin in anything to have meaning on it

val router = routing {        // 1
    handle(path = "/hello") { // 2
        // ...
    }
}

router.call(uri = "/hello")  // 3

This is the simplest code of a route system. What it means?

  1. Creating the route system to register or call routes
  2. Subscribe to a specific route to execute something related
  3. Invoke a specific route to be executed

That shows nothing new to whom already works with a route system. But this structure works in any KMP target.
Let's checkout what more kotlin routing has.

Named Routing

Don't like working with paths? You can route using names.

val router = routing {
    handle(path = "/hello", name = "hello") {
        // ...
    }
}

router.call(name = "hello")

Routing by Method

Don't want to create another path to the same behavior? You can distinguish using methods.

val router = routing {
    handle(path = "/hello", method = RouteMethod.Push) {
        // ...
    }
    handle(path = "/hello", method = RouteMethod("your method")) {
        // ...
    }
}

router.call(uri = "/hello", method = RouteMethod.Push)
// or
router.call(uri = "/hello", method = RouteMethod("your method"))

Group Routes

Do you have sub-paths? You can group your routes

val router = routing {
    route(path = "/parent") {
        handle {
            // invoked on call to /parent
        }
        handle(path = "/child") {
            // invoked on call to /parent/child
        }
        route(path = "/brother") { 
            handle(path = "/nephew") {
                // invoked on call to /parent/brother/nephew
            }
        }
    }
}

Until now, there is no limitation to inner routes.

Path Pattern

It means you can create dynamic routing structure instead of having static ways.

val router = routing {
    handle(path = "/hello/{id}") {
        // ...
    }

    handle(path = "/hello/*") {
        // ...
    }

    handle(path = "/hello/{...}") {
        // ...
    }

    handle(path = "/hello/{param...}") {
        // ...
    }

    handle(regex = Regex("/.+/hello")) {
        // ...
    }
}

Query parameters are handled by default. You don't need any setup for them.

Checkout the ktor path pattern documentation that explains how it works.

Route Details

Having dynamic routes and behaviors we need to know what is comming when the route is invoked.

val router = routing {
    handle(path = "/hello") {
        val application = call.application
        val routeMethod = call.routeMethod
        val name = call.name
        val uri = call.uri
        val attributes = call.attributes
        val parameters = call.parameters
    }
}

router.call(uri = "/hello")

Working with Parameters

Sometimes we need to provide dynamic info to the route or handle an external route that contains other infos. There are some ways to provide dynamic info using URI and all the values are captured and put into the call.parameters.
Parameters is a Ktor data structure for associating a String with a List of Strings. All values in Parameters are String.

val router = routing {
    handle(path = "/with/{id}", name = "with") {
        val parameters = call.parameters
        // {"id": ["1234"]}
    }

    handle(path = "/query", name = "query") {
        val parameters = call.parameters
        // {"color": ["red"], "tag": ["kotlin", "routing"]}
    }

    handle(path = "/all/{id}", name = "all") {
        val parameters = call.parameters
        // {"id": ["1234"], "color": ["red"], "tag": ["kotlin", "routing"]}
    }
}

router.call(uri = "/with/1234")
router.call(uri = "/query?color=red&tag=kotlin&tag=routing")
router.call(uri = "/all/1234?color=red&tag=kotlin&tag=routing")

// same call using names
// on named routing you have to provide each parameter

router.call(name = "with", parameters = parametersOf("id", "1234"))
router.call(name = "query", parameters = parametersOf("color" to listOf("red"), "tag" to listOf("kotlin", "routing")))
router.call(name = "all", parameters = parametersOf("id" to listOf("1234"), "color" to listOf("red"), "tag" to listOf("kotlin", "routing")))

Redirect Routes

Maybe you need to redirect from one route to another.

val router = routing {
    handle(path = "/hello") {
        call.redirectToPath(path = "/other-path")
        // or
        call.redirectToName(name = "other-name")
    }
}

router.call(uri = "/hello")

On demand handling

You don't need to declare all routes on the Routing creation. Subscribe and Unsubscribe to a route is available anytime with a Routing instance.

val router = routing {}

router.handle(path = "/hello", name = "hello") {
    // ...
}

router.unregisterNamed(name = "hello")
router.unregisterPath(path = "/hello")

Nested Routing

Some projects are multi-module or have features installed on demand (Dynamic Features in the Android world).
Each project/module can have your internal routing flow. Maybe connected to a parent routing flow. Nested routing provide this connection on demand.

val parent = routing { }

val featureARouting = routing(
    rootPath = "/feature-a",
    parent = parent,
) { }

val featureBRouting = routing(
    rootPath = "/feature-b",
    parent = parent,
) { }

// Try to route internaly on feature A module. 
// If not found, look up the route on parent
// It has no access to feature B routes
featureARouting.call(...)

// Same behavior as A above. 
// And it has no access to feature A routes
featureBRouting.call(...)

// Routing from parent directly to a route inside feature A
parent.call(path = "/feature-a/something")

// Routing from parent directly to a route inside feature B
parent.call(path = "/feature-b/something")

Nested routing behaviors as Group Routes section tranforming each Routing child in a Route that can be invoked.

Conclusion

Kotlin Routing bring all the power provided by the Ktor server structure to KMP world in a way that can be used in any context that needs a routing system.
Samples in the article are generics and simple to show that you can extend it to any situation you have.
There are a lot of behaviors that you can create from that. Some of them are already provided in the repository as:

All ktor plugins structure still working in the Kotlin Routing and your can creates your own.

More articles about other modules and integrations come soon.

Bonus 1 - Routing Natives

Think in a scenario that your Android Project (no KMP) are using its own navigation (Jetpack Navigation, Your custom navigation, etc.), iOS Project has its own navigation (XCoordinator, etc.) and web with React, Vue, etc. How can you connect them with you KMP new project? Kotlin Routing helps with that:

// commonMain

val router = routing {
    // ...
}

router.call(uri = "/something")

// androidMain or a non KMP android project

router.handle(path = "/something") {
    // Start an Activity?
    // Show a Fragment?
    // Call an Android navigation
    // You are free
}

// iosMain or a non KMP ios project

router.handle(path = "/something") {
    // Show a UIViewController?
    // Call an iOS navigation
    // Update a SwiftUI view
    // You are free
}

// jsMain or a non KMP web project

router.handle(path = "/something") {
    // Call react navigation
    // Call vue navigation
    // Update the DOM
    // You are free
}

Bonus 2 - Deeplinks

What about deeplinks? Deeplinks are URI and supported by default. They aren't handled by default on each platform entrypoint. You have to provide the start point. E.g:

// commonMain
val router = routing {
    handle(path = "scheme://host/path/{field}?query=q") {
    }
}

// android project
class LaunchActivity : ... {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        // Ensure that you Routing is initialized

        val action: String? = intent?.action
        val data: Uri? = intent?.data

        router.call(uri = data?.toString() ?: "/home")
    }
}

// ios project
import SwiftUI
import YourFrameworkHavingKotlinRouting

@main
struct SampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL { url in
                    router.call(uri = url.absoluteString)
                }
        }
    }
}
...

✅ Kotlin Multiplataforma 101: Entendendo como o Kotlin compila para múltiplas plataformas


📈 26.87 Punkte

✅ heise-Angebot: Rheinwerk Konferenz für Kotlin: Ein Tag voller Kotlin am 22. April


📈 26.87 Punkte

✅ Kotlin: Using WorkManager Kotlin APIs - MAD Skills


📈 26.87 Punkte

✅ Kotlin: Using Room Kotlin APIs - MAD Skills


📈 26.87 Punkte

✅ Kotlin 1.3.6 ist da: Update bringt Kotlin Worksheets


📈 26.87 Punkte

✅ Programmiersprachen: Kotlin 1.3.40 liefert Erweiterungen für Kotlin/JS und überarbeitet Typinferenz


📈 26.87 Punkte

✅ Learn Kotlin Fast with new Kotlin Bootcamp course


📈 26.87 Punkte

✅ Programmiersprachen: Kotlin 1.2 RC ist freigegeben und Kotlin/Native unterstützt iOS


📈 26.87 Punkte

✅ Decoding Kotlin - Your guide to solving the mysterious in Kotlin


📈 26.87 Punkte

✅ Mag:3 Classics Device Charging Tray review: a place for everything, and everything in its place


📈 17.37 Punkte

✅ Everything Open 2024 | Registration is now available for Everything Open 2024 - powering the future


📈 17.37 Punkte

✅ Medium CVE-2016-10917: Search everything project Search everything


📈 17.37 Punkte

✅ Programmiersprache: Kotlin/Native stellt die Speicherverwaltung um


📈 13.44 Punkte

✅ Mendel Linux 4.0, Advanced Android with Kotlin, Stackdriver Logging, & more!


📈 13.44 Punkte

✅ How to Create a Shayari Android App Using Firebase in Kotlin?


📈 13.44 Punkte

✅ Statt Java: Meta portiert sämtliche Anroid-Apps auf Kotlin


📈 13.44 Punkte

✅ Android Malware Developed in Kotlin Programming Language Found in Google Play


📈 13.44 Punkte

✅ Google: This Kotlin tool will help your Android apps build faster


📈 13.44 Punkte

✅ Netflix setzt bei einer iOS-App nun ganz auf Android-Sprache Kotlin


📈 13.44 Punkte

✅ Kilua - new Kotlin/Wasm web framework


📈 13.44 Punkte

✅ Why Kotlin is a Prime Choice for Your Project


📈 13.44 Punkte

✅ Building a Real-Time Streaming Chatbot with Kotlin and Ollama AI


📈 13.44 Punkte

✅ Am Mittwoch online: WeAreDevelopers Live Week – u.a. mit Kotlin und John Romero


📈 13.44 Punkte

✅ Android Kotlin codelab courses, Firebase Realtime Database, Chrome 78 Beta, & more!


📈 13.44 Punkte

✅ Kotlin is `fun` - Function types, lambdas, and higher-order functions


📈 13.44 Punkte

✅ Kotlin in 100 Seconds


📈 13.44 Punkte

✅ Google Pushes Kotlin Over Java for Android Development


📈 13.44 Punkte

✅ Android-Entwicklung: UI-Toolkit Jetpack Compose arbeitet mit aktuellem Kotlin


📈 13.44 Punkte

✅ Android-Programmiersprache: Google unterstützt Kotlin


📈 13.44 Punkte

✅ Tip calculator app - Android Basics in Kotlin


📈 13.44 Punkte

✅ Kotlin 2.0 ist mit K2-Compiler auf Multiplattform-Entwicklung ausgelegt


📈 13.44 Punkte

✅ From Kotlin Scripting to Python


📈 13.44 Punkte











matomo

Datei nicht gefunden!