Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ktor Routing: How to factorize the routing functionality in an application/api?

Tags:

kotlin

ktor

My question is about the big picture behind routing functionality in Ktor; and scalability when it comes to design an API with large number of routes.

If I create an app like this:

import io.ktor.application.*
import io.ktor.response.*
import io.ktor.request.*
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty

fun Application.routingExample() {
 intercept(ApplicationCallPipeline.Call){
   if (call.request.uri == "/") call.respondText("User call for /")
 }
}

fun main(args: Array<String>) {
    embeddedServer(Netty, 8080, watchPaths = listOf("Routing"), module = Application::routingExample).start()
}

Which is ok if I have an api/app with low number of routes. However in what style I should scale this approach for large number of routes (e.g., 30 routes and controller functions).

I would have a number of choices:

A large routing function: I would have a large Application.routingExample function that would hold all the routes, so I don't need to update the main.

A large main function: Would have a large function that would hold the calls to different smaller functions; but it would be repetitive; as for an API I want to serve them in the same port.

So my question is about the coding style: is there a way to to factorize the routing controller relationship?

like image 287
o-0 Avatar asked Feb 22 '18 04:02

o-0


People also ask

What is routing in KTOR?

Routing is the core Ktor plugin for handling incoming requests in a server application. When the client makes a request to a specific URL (for example, /hello ), the routing mechanism allows us to define how we want this request to be served.

Is KTOR a backend?

Ktor is an asynchronous framework used in development of microservices and web applications. Kotlin is the language used in Ktor. As we know Kotlin is getting more and more attention in development of applications for both web and mobile, at the same time it is being in use for the backend development for sometime now.


1 Answers

First, there is a sophisticated routing feature, so you don't need to compare request URIs.

Second, since the routing is a DSL and thus just code, you can extract functions and organize your code in whatever manner you like. One example is KotlinConf backend application. Source code is available here: https://github.com/JetBrains/kotlinconf-app/blob/master/backend/src/org/jetbrains/kotlinconf/backend/Api.kt

It looks like this:

fun Routing.api(database: Database, production: Boolean) {
    apiKeynote(database, production)
    apiRegister(database, production)
    apiAll(database, production)
    apiSession(database, production)
    apiVote(database, production)
    apiFavorite(database, production)
    wsVotes(database, production)
}

Each function is an extension to Routing and defines its own set of API endpoints, something like this:

fun Routing.apiFavorite(database: Database, production: Boolean) {
    route("favorites") {
        get { … }
        post { … }
        delete { … }
    }
}

You can put them in different files, folders or packages, along with the business logic, support systems, etc.

like image 89
Ilya Ryzhenkov Avatar answered Oct 26 '22 22:10

Ilya Ryzhenkov