简体   繁体   中英

Kotlin Ktor API

For my study I have an small API to developp using Kotlin and Ktor. The goal is to show JSON informations when launching the application. The information should be seen when we have http://127.0.0.1:8080/course/ {id} in our web browser. The id is some course id which can only be egal to 1,2,3 if the id is different than an error message is shown on the browser.

My code today is

fun main(args: Array<String>): Unit = 
io.ktor.server.netty.EngineMain.main(args)

@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {


install(ContentNegotiation) {
    jackson {
        enable(SerializationFeature.INDENT_OUTPUT)
    }
}

routing {
    get("/") {
        call.respondText("Welcome to OpenClassrooms brand new server !", contentType = ContentType.Text.Plain)
    }

    get("/course/top") {
        call.respond(mapOf("id" to courses[0].id, "title" to courses[0].title, "level" to courses[0].level, "isActive" to courses[0].isActive))
    }

    for (i in 0..2){
        get("/course/${i.addOneToInt()}") {
            call.respond(mapOf("id" to courses[i].id, "title" to courses[i].title, "level" to courses[i].level, "isActive" to courses[i].isActive))
        }
    }
}
}

data class Course(val id: Int, val title: String, val level: Int, val isActive: Boolean)

val courses = Collections.synchronizedList(listOf(
Course(1, "How to troll a Troll?",5,true),
Course(2, "Kotlin for Troll",1,true),
Course(3, "Kotlin vs Java",3,true))
)

I am not very friendly with kotlin and ktor. The application is working for the moment but I do not know how to cover the error message when id is not egal to 1,2,3. if I have http://127.0.0.1:8080/course/4 for example i have an error saying that the website page is invalid. I would like to show instead :

call.respond(mapOf("status" to "404", "message: no course found!"))

Could someone help me ?

Thanks

In this case Ktor already responds with "404 not found".

Nevertheless if you want to add your own message remove the for loop and replace it by a URL parameter.

Then create your own response if the course id can not be found.

routing {

    // .....

    get("/course/{courseId}") {
        val i = call.parameters["courseId"]!!.toInt() - 1
        if (i < 0 || i >= courses.size) {
            call.respond(HttpStatusCode.NotFound, "no course found!")
        } else {
            call.respond(
                mapOf(
                    "id" to courses[i].id,
                    "title" to courses[i].title,
                    "level" to courses[i].level,
                    "isActive" to courses[i].isActive
                )
            )
        }
    }

}

I agree with Egger's answer, but I don't believe you would need to specify the mapped fields if you're going to simply translate the whole object into JSON. You could just respond with the object itself and let Ktor handle it.

routing {

    // .....

    get("/course/{courseId}") {
        val i = call.parameters["courseId"]!!.toInt() - 1
        if (i < 0 || i >= courses.size) {
            call.respond(HttpStatusCode.NotFound, "no course found!")
        } else {
            call.respond(courses[i])
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM