Ktor is an asynchronous framework for creating microservices, web applications, and more. It’s fun, free, and open source.
Just like any Java Spring Boot Application, Ktor also has its own Application file. So lets start from it by comparing a spring boot application file with a Ktor.
public static void main(String[] args) { | |
SpringApplication.run(CloudStorageApplication.class, args); | |
} |
A Ktor application file:
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) | |
fun Application.module() { | |
} |
As you can see, both files have a main method that receives as an argument an array of strings, but Ktor uses its main method to create an embedded netty application.
In a Spring Application we would create a controller class responsible to handle all http requests to an endpoint by making use of java annotations. In Ktor, we need to create a kotlin file to represent our Application Routes by using the Ktor Route class. As you can see we make use of the route method to define our endpoint as well as all our http methods.
fun Route.userRouting() { | |
// Defining the user endpoint | |
route("/user") { | |
get { | |
} | |
get("{id}") { | |
} | |
post { | |
} | |
delete("id") { | |
} | |
} | |
} |
Next we need to work in each individual http request. Lets start with our GET request. But before we do so we need to create a data class in the same way we would create our POJO for our model or entity class in Spring. So, lets do just that:
@Serializable | |
data class User(val id: Int, val firstName: String, val lastName: String, val email: String, val password: String) |
By adding the val in front of each constructor parameter we are turning them into class properties so we don´t have to write any getters or setters to them, but in doing so we are actually using a Kotlin convention to create immutable and safer objects. Adding the serializable annotation to our data class will let Ktor know how to handle the serialization properly for us so we can just use our kotlin object to answer to the http request. So lets see how that work in code by changing our get handler in the userRoutes.kt file:
get { | |
if (users.isNotEmpty()) { | |
call.respond(users) | |
} else { | |
call.respondText("No users found", status = HttpStatusCode.NotFound) | |
} | |
} |
As you can see, we can just use the call.respond function to answer to the http get request by passing a kotlin object to it and if our list of users are empty we can just use the call.respondText function to respond with a plain text message and an optional http status code, because the default value is HttpStatusCode.OK. So, before we do just that, lets create a mutable list of users so we can use them in our post handler to add new users!
@Serializable | |
data class Customer(val id: String, val firstName: String, val lastName: String, val email: String) | |
val users = mutableListOf<User>() |
Instead of using the call.respond function as we would normally do it in a get request we can now make use of the call.receive function and since we have annotated our data class as serializable, we can now automatically deserialize the JSON request body into a Kotlin User object and use it to add it to our list of users.
post { | |
val user = call.receive<User>() | |
users.add(user) | |
call.respondText( | |
"User added correctly!", | |
status = HttpStatusCode.Created | |
) | |
} |
Comments
Post a Comment