CodeBlanks Logo Icon CodeBlanks

Ktor API

Set up the REST API skeleton with Ktor.

Routing with the Api class

The second lesson adds the Api class. It takes a UserRepo; the route(path) method interprets a URL path. This mimics Ktor's routing layer at a small scale.

Example: class Api(val repo: UserRepo). Calling route("/users/1") extracts id=1, finds the user via repo.find(1) and returns its name. Unknown paths return "404". This pattern connects HTTP requests to business logic.

route and startsWith

The route method recognizes the path with path.startsWith("/users/"). With removePrefix it extracts the id part; with toInt() it converts it to a number.

Example: path.removePrefix("/users/").toInt(). The path "/users/1" gives id 1. This value is passed to repo.find(id). This pattern is a concise way to extract parameters from a URL; it resembles Ktor's @Location pattern.

Practice Add the Api class

Keep the existing User and UserRepo definitions. Add class Api(val repo: UserRepo) with method fun route(path: String): String. The method, if path.startsWith("/users/"), extracts the id and returns repo.find(id)?.name ?: "not found"; otherwise returns "404". In main add User(1, "Alex"), create Api(repo) and print println(api.route("/users/1")).

Starter code

Main.kt
data class User(val id: Int, val name: String)

class UserRepo {
    private val users = mutableListOf<User>()
    fun save(u: User) { users.add(u) }
    fun find(id: Int): User? = users.find { it.id == id }
}

fun main() {
    val repo = UserRepo()
    repo.save(User(1, "Alex"))
    println(repo.find(1))
}

// Api class: route method
// in main create api, print /users/1 call

Sample solution

Main.kt
data class User(val id: Int, val name: String)

class UserRepo {
    private val users = mutableListOf<User>()
    fun save(u: User) { users.add(u) }
    fun find(id: Int): User? = users.find { it.id == id }
}

class Api(val repo: UserRepo) {
    fun route(path: String): String {
        return when {
            path.startsWith("/users/") -> {
                val id = path.removePrefix("/users/").toInt()
                repo.find(id)?.name ?: "not found"
            }
            else -> "404"
        }
    }
}

fun main() {
    val repo = UserRepo()
    repo.save(User(1, "Alex"))
    val api = Api(repo)
    println(api.route("/users/1"))
}

Expected output

Alex

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Complete the Api class definition

Question
____ Api(val repo: UserRepo)
Answer
class Api(val repo: UserRepo)

Explanation: class Api declares a class.

2 Match the Api parts

Term Meaning
class Api(val repo) Api class
route(path) Routing
startsWith("/users/") Path match
removePrefix Id extract

3 What does Api.route return for an unknown path?

  • null
  • Empty list
  • "404" Correct answer
  • Throws an exception

Explanation: Unknown paths return "404".

All lessons in Advanced